159599516SKenneth E. Jansen /* 259599516SKenneth E. Jansen * 359599516SKenneth E. Jansen * This is the SyncIO library that uses MPI-IO collective functions to 459599516SKenneth E. Jansen * implement a flexible I/O checkpoint solution for a large number of 559599516SKenneth E. Jansen * processors. 659599516SKenneth E. Jansen * 759599516SKenneth E. Jansen * Previous developer: Ning Liu (liun2@cs.rpi.edu) 859599516SKenneth E. Jansen * Jing Fu (fuj@cs.rpi.edu) 959599516SKenneth E. Jansen * Current developers: Michel Rasquin (Michel.Rasquin@colorado.edu), 1059599516SKenneth E. Jansen * Ben Matthews (benjamin.a.matthews@colorado.edu) 1159599516SKenneth E. Jansen * 1259599516SKenneth E. Jansen */ 1359599516SKenneth E. Jansen 1459599516SKenneth E. Jansen #include <map> 1559599516SKenneth E. Jansen #include <vector> 1659599516SKenneth E. Jansen #include <string> 1759599516SKenneth E. Jansen #include <string.h> 1859599516SKenneth E. Jansen #include <ctype.h> 1959599516SKenneth E. Jansen #include <stdlib.h> 2059599516SKenneth E. Jansen #include <stdio.h> 2159599516SKenneth E. Jansen #include <math.h> 22d3337298SCameron Smith #include <sstream> 2359599516SKenneth E. Jansen #include "phastaIO.h" 2459599516SKenneth E. Jansen #include "mpi.h" 2559599516SKenneth E. Jansen #include "phiotmrc.h" 26*97a07b0aSCameron Smith #include <assert.h> 2759599516SKenneth E. Jansen 2859599516SKenneth E. Jansen #define VERSION_INFO_HEADER_SIZE 8192 2959599516SKenneth E. Jansen #define DB_HEADER_SIZE 1024 3059599516SKenneth E. Jansen #define ONE_MEGABYTE 1048576 3159599516SKenneth E. Jansen #define TWO_MEGABYTE 2097152 3259599516SKenneth E. Jansen #define ENDIAN_TEST_NUMBER 12180 // Troy's Zip Code!! 3359599516SKenneth E. Jansen #define MAX_PHASTA_FILES 64 3459599516SKenneth E. Jansen #define MAX_PHASTA_FILE_NAME_LENGTH 1024 3559599516SKenneth E. Jansen #define MAX_FIELDS_NUMBER ((VERSION_INFO_HEADER_SIZE/MAX_FIELDS_NAME_LENGTH)-4) // The meta data include - MPI_IO_Tag, nFields, nFields*names of the fields, nppf 3659599516SKenneth E. Jansen // -3 for MPI_IO_Tag, nFields and nppf, -4 for extra security (former nFiles) 3759599516SKenneth E. Jansen #define MAX_FIELDS_NAME_LENGTH 128 3859599516SKenneth E. Jansen #define DefaultMHSize (4*ONE_MEGABYTE) 3959599516SKenneth E. Jansen //#define DefaultMHSize (8350) //For test 4059599516SKenneth E. Jansen #define LATEST_WRITE_VERSION 1 4159599516SKenneth E. Jansen #define inv1024sq 953.674316406e-9 // = 1/1024/1024 4259599516SKenneth E. Jansen int MasterHeaderSize = -1; 4359599516SKenneth E. Jansen 4459599516SKenneth E. Jansen bool PRINT_PERF = false; // default print no perf results 4559599516SKenneth E. Jansen int irank = -1; // global rank, should never be manually manipulated 4659599516SKenneth E. Jansen int mysize = -1; 4759599516SKenneth E. Jansen 4859599516SKenneth E. Jansen // Static variables are bad but used here to store the subcommunicator and associated variables 4959599516SKenneth E. Jansen // Prevent MPI_Comm_split to be called more than once, especially on BGQ with the V1R2M1 driver (leak detected in MPI_Comm_split - IBM working on it) 5059599516SKenneth E. Jansen static int s_assign_local_comm = 0; 5159599516SKenneth E. Jansen static MPI_Comm s_local_comm; 5259599516SKenneth E. Jansen static int s_local_size = -1; 5359599516SKenneth E. Jansen static int s_local_rank = -1; 5459599516SKenneth E. Jansen 5559599516SKenneth E. Jansen // the following defines are for debug printf 5659599516SKenneth E. Jansen #define PHASTAIO_DEBUG 0 //default to not print any debugging info 5759599516SKenneth E. Jansen 58fe03b87fSCameron Smith void phprintf(const char* fmt, ...) { 5959599516SKenneth E. Jansen #if PHASTAIO_DEBUG 60fe03b87fSCameron Smith char format[1024]; 61fe03b87fSCameron Smith snprintf(format, sizeof(format), "phastaIO debug: %s", fmt); 62fe03b87fSCameron Smith va_list ap; 63fe03b87fSCameron Smith va_start(ap,fmt); 64fe03b87fSCameron Smith vprintf(format,ap) 65fe03b87fSCameron Smith va_end(ap); 6659599516SKenneth E. Jansen #endif 67fe03b87fSCameron Smith } 68fe03b87fSCameron Smith 69fe03b87fSCameron Smith void phprintf_0(const char* fmt, ...) { 70fe03b87fSCameron Smith #if PHASTAIO_DEBUG 71fe03b87fSCameron Smith int rank = 0; 72fe03b87fSCameron Smith MPI_Comm_rank(MPI_COMM_WORLD, &rank); 73fe03b87fSCameron Smith if(rank == 0){ 74fe03b87fSCameron Smith char format[1024]; 75fe03b87fSCameron Smith snprintf(format, sizeof(format), "phastaIO debug: irank=0 %s", fmt); 76fe03b87fSCameron Smith va_list ap; 77fe03b87fSCameron Smith va_start(ap,s); 78fe03b87fSCameron Smith vprintf(format, ap); 79fe03b87fSCameron Smith va_end(ap); 80fe03b87fSCameron Smith } 81fe03b87fSCameron Smith #endif 82fe03b87fSCameron Smith } 8359599516SKenneth E. Jansen 8459599516SKenneth E. Jansen enum PhastaIO_Errors 8559599516SKenneth E. Jansen { 8659599516SKenneth E. Jansen MAX_PHASTA_FILES_EXCEEDED = -1, 8759599516SKenneth E. Jansen UNABLE_TO_OPEN_FILE = -2, 8859599516SKenneth E. Jansen NOT_A_MPI_FILE = -3, 8959599516SKenneth E. Jansen GPID_EXCEEDED = -4, 9010d56689SCameron Smith DATA_TYPE_ILLEGAL = -5 9159599516SKenneth E. Jansen }; 9259599516SKenneth E. Jansen 9359599516SKenneth E. Jansen using namespace std; 9459599516SKenneth E. Jansen 9559599516SKenneth E. Jansen namespace{ 9659599516SKenneth E. Jansen 97961a4ff6SCameron Smith map<int, std::string> LastHeaderKey; 9859599516SKenneth E. Jansen vector< FILE* > fileArray; 9959599516SKenneth E. Jansen vector< bool > byte_order; 10059599516SKenneth E. Jansen vector< int > header_type; 10159599516SKenneth E. Jansen int DataSize=0; 10259599516SKenneth E. Jansen bool LastHeaderNotFound = false; 10359599516SKenneth E. Jansen bool Wrong_Endian = false ; 10459599516SKenneth E. Jansen bool Strict_Error = false ; 10559599516SKenneth E. Jansen bool binary_format = true; 10659599516SKenneth E. Jansen 10759599516SKenneth E. Jansen /***********************************************************************/ 10859599516SKenneth E. Jansen /***************** NEW PHASTA IO CODE STARTS HERE **********************/ 10959599516SKenneth E. Jansen /***********************************************************************/ 11059599516SKenneth E. Jansen 11159599516SKenneth E. Jansen typedef struct 11259599516SKenneth E. Jansen { 11359599516SKenneth E. Jansen char filename[MAX_PHASTA_FILE_NAME_LENGTH]; /* defafults to 1024 */ 1142dd307a1SCameron Smith unsigned long my_offset; 1152dd307a1SCameron Smith unsigned long next_start_address; 1162dd307a1SCameron Smith unsigned long **my_offset_table; 1172dd307a1SCameron Smith unsigned long **my_read_table; 11859599516SKenneth E. Jansen 11959599516SKenneth E. Jansen double * double_chunk; 12059599516SKenneth E. Jansen double * read_double_chunk; 12159599516SKenneth E. Jansen 12259599516SKenneth E. Jansen int field_count; 12359599516SKenneth E. Jansen int part_count; 12459599516SKenneth E. Jansen int read_field_count; 12559599516SKenneth E. Jansen int read_part_count; 12659599516SKenneth E. Jansen int GPid; 12759599516SKenneth E. Jansen int start_id; 12859599516SKenneth E. Jansen 12959599516SKenneth E. Jansen int mhsize; 13059599516SKenneth E. Jansen 13159599516SKenneth E. Jansen int myrank; 13259599516SKenneth E. Jansen int numprocs; 13359599516SKenneth E. Jansen int local_myrank; 13459599516SKenneth E. Jansen int local_numprocs; 13559599516SKenneth E. Jansen 13659599516SKenneth E. Jansen int nppp; 13759599516SKenneth E. Jansen int nPPF; 13859599516SKenneth E. Jansen int nFiles; 13959599516SKenneth E. Jansen int nFields; 14059599516SKenneth E. Jansen 14159599516SKenneth E. Jansen int * int_chunk; 14259599516SKenneth E. Jansen int * read_int_chunk; 14359599516SKenneth E. Jansen 14459599516SKenneth E. Jansen int Wrong_Endian; /* default to false */ 14559599516SKenneth E. Jansen char * master_header; 14659599516SKenneth E. Jansen MPI_File file_handle; 14759599516SKenneth E. Jansen MPI_Comm local_comm; 14859599516SKenneth E. Jansen } phastaio_file_t; 14959599516SKenneth E. Jansen 15059599516SKenneth E. Jansen typedef struct 15159599516SKenneth E. Jansen { 15259599516SKenneth E. Jansen int nppf, nfields; 15359599516SKenneth E. Jansen char * masterHeader; 15459599516SKenneth E. Jansen }serial_file; 15559599516SKenneth E. Jansen 15659599516SKenneth E. Jansen serial_file *SerialFile; 15759599516SKenneth E. Jansen phastaio_file_t *PhastaIOActiveFiles[MAX_PHASTA_FILES]; 15859599516SKenneth E. Jansen int PhastaIONextActiveIndex = 0; /* indicates next index to allocate */ 15959599516SKenneth E. Jansen 16059599516SKenneth E. Jansen // the caller has the responsibility to delete the returned string 16159599516SKenneth E. Jansen // TODO: StringStipper("nbc value? ") returns NULL? 16259599516SKenneth E. Jansen char* 16359599516SKenneth E. Jansen StringStripper( const char istring[] ) { 16459599516SKenneth E. Jansen 16559599516SKenneth E. Jansen int length = strlen( istring ); 16659599516SKenneth E. Jansen 16759599516SKenneth E. Jansen char* dest = (char *)malloc( length + 1 ); 16859599516SKenneth E. Jansen 16959599516SKenneth E. Jansen strcpy( dest, istring ); 17059599516SKenneth E. Jansen dest[ length ] = '\0'; 17159599516SKenneth E. Jansen 17259599516SKenneth E. Jansen if ( char* p = strpbrk( dest, " ") ) 17359599516SKenneth E. Jansen *p = '\0'; 17459599516SKenneth E. Jansen 17559599516SKenneth E. Jansen return dest; 17659599516SKenneth E. Jansen } 17759599516SKenneth E. Jansen 17859599516SKenneth E. Jansen inline int 17959599516SKenneth E. Jansen cscompare( const char teststring[], 18059599516SKenneth E. Jansen const char targetstring[] ) { 18159599516SKenneth E. Jansen 18259599516SKenneth E. Jansen char* s1 = const_cast<char*>(teststring); 18359599516SKenneth E. Jansen char* s2 = const_cast<char*>(targetstring); 18459599516SKenneth E. Jansen 18559599516SKenneth E. Jansen while( *s1 == ' ') s1++; 18659599516SKenneth E. Jansen while( *s2 == ' ') s2++; 18759599516SKenneth E. Jansen while( ( *s1 ) 18859599516SKenneth E. Jansen && ( *s2 ) 18959599516SKenneth E. Jansen && ( *s2 != '?') 19059599516SKenneth E. Jansen && ( tolower( *s1 )==tolower( *s2 ) ) ) { 19159599516SKenneth E. Jansen s1++; 19259599516SKenneth E. Jansen s2++; 19359599516SKenneth E. Jansen while( *s1 == ' ') s1++; 19459599516SKenneth E. Jansen while( *s2 == ' ') s2++; 19559599516SKenneth E. Jansen } 19659599516SKenneth E. Jansen if ( !( *s1 ) || ( *s1 == '?') ) return 1; 19759599516SKenneth E. Jansen else return 0; 19859599516SKenneth E. Jansen } 19959599516SKenneth E. Jansen 20059599516SKenneth E. Jansen inline void 20159599516SKenneth E. Jansen isBinary( const char iotype[] ) { 20259599516SKenneth E. Jansen 20359599516SKenneth E. Jansen char* fname = StringStripper( iotype ); 20459599516SKenneth E. Jansen if ( cscompare( fname, "binary" ) ) binary_format = true; 20559599516SKenneth E. Jansen else binary_format = false; 20659599516SKenneth E. Jansen free (fname); 20759599516SKenneth E. Jansen 20859599516SKenneth E. Jansen } 20959599516SKenneth E. Jansen 21059599516SKenneth E. Jansen inline size_t 21159599516SKenneth E. Jansen typeSize( const char typestring[] ) { 21259599516SKenneth E. Jansen 21359599516SKenneth E. Jansen char* ts1 = StringStripper( typestring ); 21459599516SKenneth E. Jansen 21559599516SKenneth E. Jansen if ( cscompare( "integer", ts1 ) ) { 21659599516SKenneth E. Jansen free (ts1); 21759599516SKenneth E. Jansen return sizeof(int); 21859599516SKenneth E. Jansen } else if ( cscompare( "double", ts1 ) ) { 21959599516SKenneth E. Jansen free (ts1); 22059599516SKenneth E. Jansen return sizeof( double ); 22159599516SKenneth E. Jansen } else { 22259599516SKenneth E. Jansen free (ts1); 22359599516SKenneth E. Jansen fprintf(stderr,"unknown type : %s\n",ts1); 22459599516SKenneth E. Jansen return 0; 22559599516SKenneth E. Jansen } 22659599516SKenneth E. Jansen } 22759599516SKenneth E. Jansen 22859599516SKenneth E. Jansen int 22959599516SKenneth E. Jansen readHeader( FILE* fileObject, 23059599516SKenneth E. Jansen const char phrase[], 23159599516SKenneth E. Jansen int* params, 23259599516SKenneth E. Jansen int expect ) { 23359599516SKenneth E. Jansen 23459599516SKenneth E. Jansen char* text_header; 23559599516SKenneth E. Jansen char* token; 236*97a07b0aSCameron Smith char Line[1024] = "\0"; 23759599516SKenneth E. Jansen char junk; 23859599516SKenneth E. Jansen bool FOUND = false ; 23959599516SKenneth E. Jansen int real_length; 24059599516SKenneth E. Jansen int skip_size, integer_value; 24159599516SKenneth E. Jansen int rewind_count=0; 24259599516SKenneth E. Jansen 24359599516SKenneth E. Jansen if( !fgets( Line, 1024, fileObject ) && feof( fileObject ) ) { 24459599516SKenneth E. Jansen rewind( fileObject ); 24559599516SKenneth E. Jansen clearerr( fileObject ); 24659599516SKenneth E. Jansen rewind_count++; 24759599516SKenneth E. Jansen fgets( Line, 1024, fileObject ); 24859599516SKenneth E. Jansen } 24959599516SKenneth E. Jansen 25059599516SKenneth E. Jansen while( !FOUND && ( rewind_count < 2 ) ) { 25159599516SKenneth E. Jansen if ( ( Line[0] != '\n' ) && ( real_length = strcspn( Line, "#" )) ){ 25259599516SKenneth E. Jansen text_header = (char *)malloc( real_length + 1 ); 25359599516SKenneth E. Jansen 25459599516SKenneth E. Jansen strncpy( text_header, Line, real_length ); 25559599516SKenneth E. Jansen text_header[ real_length ] =static_cast<char>(NULL); 25659599516SKenneth E. Jansen token = strtok ( text_header, ":" ); 257*97a07b0aSCameron Smith assert(token); 258*97a07b0aSCameron Smith if( cscompare( phrase , token ) ) { 25959599516SKenneth E. Jansen FOUND = true ; 26059599516SKenneth E. Jansen token = strtok( NULL, " ,;<>" ); 261*97a07b0aSCameron Smith assert(token); 26259599516SKenneth E. Jansen skip_size = atoi( token ); 26359599516SKenneth E. Jansen int i; 26459599516SKenneth E. Jansen for( i=0; i < expect && ( token = strtok( NULL," ,;<>") ); i++) { 265*97a07b0aSCameron Smith assert(token); 26659599516SKenneth E. Jansen params[i] = atoi( token ); 26759599516SKenneth E. Jansen } 26859599516SKenneth E. Jansen if ( i < expect ) { 26959599516SKenneth E. Jansen fprintf(stderr,"Aloha Expected # of ints not found for: %s\n",phrase ); 27059599516SKenneth E. Jansen } 27159599516SKenneth E. Jansen } else if ( cscompare(token,"byteorder magic number") ) { 27259599516SKenneth E. Jansen if ( binary_format ) { 27359599516SKenneth E. Jansen fread((void*)&integer_value,sizeof(int),1,fileObject); 27459599516SKenneth E. Jansen fread( &junk, sizeof(char), 1 , fileObject ); 27559599516SKenneth E. Jansen if ( 362436 != integer_value ) Wrong_Endian = true; 27659599516SKenneth E. Jansen } else{ 27759599516SKenneth E. Jansen fscanf(fileObject, "%d\n", &integer_value ); 27859599516SKenneth E. Jansen } 27959599516SKenneth E. Jansen } else { 28059599516SKenneth E. Jansen /* some other header, so just skip over */ 28159599516SKenneth E. Jansen token = strtok( NULL, " ,;<>" ); 282*97a07b0aSCameron Smith assert(token); 28359599516SKenneth E. Jansen skip_size = atoi( token ); 28459599516SKenneth E. Jansen if ( binary_format) 28559599516SKenneth E. Jansen fseek( fileObject, skip_size, SEEK_CUR ); 28659599516SKenneth E. Jansen else 28759599516SKenneth E. Jansen for( int gama=0; gama < skip_size; gama++ ) 28859599516SKenneth E. Jansen fgets( Line, 1024, fileObject ); 28959599516SKenneth E. Jansen } 29059599516SKenneth E. Jansen free (text_header); 29159599516SKenneth E. Jansen } // end of if before while loop 29259599516SKenneth E. Jansen 29359599516SKenneth E. Jansen if ( !FOUND ) 29459599516SKenneth E. Jansen if( !fgets( Line, 1024, fileObject ) && feof( fileObject ) ) { 29559599516SKenneth E. Jansen rewind( fileObject ); 29659599516SKenneth E. Jansen clearerr( fileObject ); 29759599516SKenneth E. Jansen rewind_count++; 29859599516SKenneth E. Jansen fgets( Line, 1024, fileObject ); 29959599516SKenneth E. Jansen } 30059599516SKenneth E. Jansen } 30159599516SKenneth E. Jansen 30259599516SKenneth E. Jansen if ( !FOUND ) { 30359599516SKenneth E. Jansen //fprintf(stderr, "Error: Could not find: %s\n", phrase); 30459599516SKenneth E. Jansen if(irank == 0) printf("WARNING: Could not find: %s\n", phrase); 30559599516SKenneth E. Jansen return 1; 30659599516SKenneth E. Jansen } 30759599516SKenneth E. Jansen return 0; 30859599516SKenneth E. Jansen } 30959599516SKenneth E. Jansen 31059599516SKenneth E. Jansen } // end unnamed namespace 31159599516SKenneth E. Jansen 31259599516SKenneth E. Jansen 31359599516SKenneth E. Jansen // begin of publicly visible functions 31459599516SKenneth E. Jansen 31559599516SKenneth E. Jansen /** 31659599516SKenneth E. Jansen * This function takes a long long pointer and assign (start) phiotmrc value to it 31759599516SKenneth E. Jansen */ 31859599516SKenneth E. Jansen void startTimer(double* start) { 31959599516SKenneth E. Jansen 32059599516SKenneth E. Jansen if( !PRINT_PERF ) return; 32159599516SKenneth E. Jansen 32259599516SKenneth E. Jansen MPI_Barrier(MPI_COMM_WORLD); 32359599516SKenneth E. Jansen *start = phiotmrc(); 32459599516SKenneth E. Jansen } 32559599516SKenneth E. Jansen 32659599516SKenneth E. Jansen /** 32759599516SKenneth E. Jansen * This function takes a long long pointer and assign (end) phiotmrc value to it 32859599516SKenneth E. Jansen */ 32959599516SKenneth E. Jansen void endTimer(double* end) { 33059599516SKenneth E. Jansen 33159599516SKenneth E. Jansen if( !PRINT_PERF ) return; 33259599516SKenneth E. Jansen 33359599516SKenneth E. Jansen *end = phiotmrc(); 33459599516SKenneth E. Jansen MPI_Barrier(MPI_COMM_WORLD); 33559599516SKenneth E. Jansen } 33659599516SKenneth E. Jansen 33759599516SKenneth E. Jansen /** 33859599516SKenneth E. Jansen * choose to print some performance results (or not) according to 33959599516SKenneth E. Jansen * the PRINT_PERF macro 34059599516SKenneth E. Jansen */ 34159599516SKenneth E. Jansen void printPerf( 34259599516SKenneth E. Jansen const char* func_name, 34359599516SKenneth E. Jansen double start, 34459599516SKenneth E. Jansen double end, 3452dd307a1SCameron Smith unsigned long datasize, 34659599516SKenneth E. Jansen int printdatainfo, 34759599516SKenneth E. Jansen const char* extra_msg) { 34859599516SKenneth E. Jansen 34959599516SKenneth E. Jansen if( !PRINT_PERF ) return; 35059599516SKenneth E. Jansen 3512dd307a1SCameron Smith unsigned long data_size = datasize; 35259599516SKenneth E. Jansen 35359599516SKenneth E. Jansen double time = end - start; 35459599516SKenneth E. Jansen 3552dd307a1SCameron Smith unsigned long isizemin,isizemax,isizetot; 35659599516SKenneth E. Jansen double sizemin,sizemax,sizeavg,sizetot,rate; 35759599516SKenneth E. Jansen double tmin, tmax, tavg, ttot; 35859599516SKenneth E. Jansen 35959599516SKenneth E. Jansen MPI_Allreduce(&time, &tmin,1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); 36059599516SKenneth E. Jansen MPI_Allreduce(&time, &tmax,1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); 36159599516SKenneth E. Jansen MPI_Allreduce(&time, &ttot,1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); 36259599516SKenneth E. Jansen tavg = ttot/mysize; 36359599516SKenneth E. Jansen 36459599516SKenneth E. Jansen if(irank == 0) { 36559599516SKenneth E. Jansen if ( PhastaIONextActiveIndex == 0 ) printf("** 1PFPP "); 36659599516SKenneth E. Jansen else printf("** syncIO "); 36759599516SKenneth E. Jansen printf("%s(): Tmax = %f sec, Tmin = %f sec, Tavg = %f sec", func_name, tmax, tmin, tavg); 36859599516SKenneth E. Jansen } 36959599516SKenneth E. Jansen 37059599516SKenneth E. Jansen if(printdatainfo == 1) { // if printdatainfo ==1, compute I/O rate and block size 37159599516SKenneth E. Jansen MPI_Allreduce(&data_size,&isizemin,1,MPI_LONG_LONG_INT,MPI_MIN,MPI_COMM_WORLD); 37259599516SKenneth E. Jansen MPI_Allreduce(&data_size,&isizemax,1,MPI_LONG_LONG_INT,MPI_MAX,MPI_COMM_WORLD); 37359599516SKenneth E. Jansen MPI_Allreduce(&data_size,&isizetot,1,MPI_LONG_LONG_INT,MPI_SUM,MPI_COMM_WORLD); 37459599516SKenneth E. Jansen 37559599516SKenneth E. Jansen sizemin=(double)(isizemin*inv1024sq); 37659599516SKenneth E. Jansen sizemax=(double)(isizemax*inv1024sq); 37759599516SKenneth E. Jansen sizetot=(double)(isizetot*inv1024sq); 37859599516SKenneth E. Jansen sizeavg=(double)(1.0*sizetot/mysize); 37959599516SKenneth E. Jansen rate=(double)(1.0*sizetot/tmax); 38059599516SKenneth E. Jansen 38159599516SKenneth E. Jansen if( irank == 0) { 38259599516SKenneth E. Jansen printf(", Rate = %f MB/s [%s] \n \t\t\t block size: Min= %f MB; Max= %f MB; Avg= %f MB; Tot= %f MB\n", rate, extra_msg, sizemin,sizemax,sizeavg,sizetot); 38359599516SKenneth E. Jansen } 38459599516SKenneth E. Jansen } 38559599516SKenneth E. Jansen else { 38659599516SKenneth E. Jansen if(irank == 0) { 38759599516SKenneth E. Jansen printf(" \n"); 38859599516SKenneth E. Jansen //printf(" (%s) \n", extra_msg); 38959599516SKenneth E. Jansen } 39059599516SKenneth E. Jansen } 39159599516SKenneth E. Jansen } 39259599516SKenneth E. Jansen 39359599516SKenneth E. Jansen /** 39459599516SKenneth E. Jansen * This function is normally called at the beginning of a read operation, before 39559599516SKenneth E. Jansen * init function. 39659599516SKenneth E. Jansen * This function (uses rank 0) reads out nfields, nppf, master header size, 39759599516SKenneth E. Jansen * endianess and allocates for masterHeader string. 39859599516SKenneth E. Jansen * These values are essential for following read operations. Rank 0 will bcast 39959599516SKenneth E. Jansen * these values to other ranks in the commm world 40059599516SKenneth E. Jansen * 40159599516SKenneth E. Jansen * If the file set is of old POSIX format, it would throw error and exit 40259599516SKenneth E. Jansen */ 40359599516SKenneth E. Jansen void queryphmpiio(const char filename[],int *nfields, int *nppf) 40459599516SKenneth E. Jansen { 40559599516SKenneth E. Jansen MPI_Comm_rank(MPI_COMM_WORLD, &irank); 40659599516SKenneth E. Jansen MPI_Comm_size(MPI_COMM_WORLD, &mysize); 40759599516SKenneth E. Jansen 40859599516SKenneth E. Jansen if(irank == 0) { 40959599516SKenneth E. Jansen FILE * fileHandle; 41059599516SKenneth E. Jansen char* fname = StringStripper( filename ); 41159599516SKenneth E. Jansen 41259599516SKenneth E. Jansen fileHandle = fopen (fname,"rb"); 41359599516SKenneth E. Jansen if (fileHandle == NULL ) { 41459599516SKenneth E. Jansen printf("\nError: File %s doesn't exist! Please check!\n",fname); 41559599516SKenneth E. Jansen } 41659599516SKenneth E. Jansen else { 41759599516SKenneth E. Jansen SerialFile =(serial_file *)calloc( 1, sizeof( serial_file) ); 41859599516SKenneth E. Jansen int meta_size_limit = VERSION_INFO_HEADER_SIZE; 41959599516SKenneth E. Jansen SerialFile->masterHeader = (char *)malloc( meta_size_limit ); 42059599516SKenneth E. Jansen fread(SerialFile->masterHeader, 1, meta_size_limit, fileHandle); 42159599516SKenneth E. Jansen 42259599516SKenneth E. Jansen char read_out_tag[MAX_FIELDS_NAME_LENGTH]; 42359599516SKenneth E. Jansen char version[MAX_FIELDS_NAME_LENGTH/4]; 42459599516SKenneth E. Jansen int mhsize; 42559599516SKenneth E. Jansen char * token; 42659599516SKenneth E. Jansen int magic_number; 42759599516SKenneth E. Jansen 42859599516SKenneth E. Jansen memcpy( read_out_tag, 42959599516SKenneth E. Jansen SerialFile->masterHeader, 43059599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH-1 ); 43159599516SKenneth E. Jansen 43259599516SKenneth E. Jansen if ( cscompare ("MPI_IO_Tag",read_out_tag) ) { 43359599516SKenneth E. Jansen // Test endianess ... 43459599516SKenneth E. Jansen memcpy (&magic_number, 43559599516SKenneth E. Jansen SerialFile->masterHeader + sizeof("MPI_IO_Tag : ")-1, //-1 sizeof returns the size of the string+1 for "\0" 43659599516SKenneth E. Jansen sizeof(int) ); // masterheader should look like "MPI_IO_Tag : 12180 " with 12180 in binary format 43759599516SKenneth E. Jansen 43859599516SKenneth E. Jansen if ( magic_number != ENDIAN_TEST_NUMBER ) { 43959599516SKenneth E. Jansen printf("Endian is different!\n"); 44059599516SKenneth E. Jansen // Will do swap later 44159599516SKenneth E. Jansen } 44259599516SKenneth E. Jansen 44359599516SKenneth E. Jansen // test version, old version, default masterheader size is 4M 44459599516SKenneth E. Jansen // newer version masterheader size is read from first line 44559599516SKenneth E. Jansen memcpy(version, 44659599516SKenneth E. Jansen SerialFile->masterHeader + MAX_FIELDS_NAME_LENGTH/2, 44759599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH/4 - 1); //TODO: why -1? 44859599516SKenneth E. Jansen 44959599516SKenneth E. Jansen if( cscompare ("version",version) ) { 45059599516SKenneth E. Jansen // if there is "version" tag in the file, then it is newer format 45159599516SKenneth E. Jansen // read master header size from here, otherwise use default 45259599516SKenneth E. Jansen // Note: if version is "1", we know mhsize is at 3/4 place... 45359599516SKenneth E. Jansen 45459599516SKenneth E. Jansen token = strtok(version, ":"); 45559599516SKenneth E. Jansen token = strtok(NULL, " ,;<>" ); 45659599516SKenneth E. Jansen int iversion = atoi(token); 45759599516SKenneth E. Jansen 45859599516SKenneth E. Jansen if( iversion == 1) { 45959599516SKenneth E. Jansen memcpy( &mhsize, 46059599516SKenneth E. Jansen SerialFile->masterHeader + MAX_FIELDS_NAME_LENGTH/4*3 + sizeof("mhsize : ")-1, 46159599516SKenneth E. Jansen sizeof(int)); 46259599516SKenneth E. Jansen if ( magic_number != ENDIAN_TEST_NUMBER ) 46359599516SKenneth E. Jansen SwapArrayByteOrder(&mhsize, sizeof(int), 1); 46459599516SKenneth E. Jansen 46559599516SKenneth E. Jansen if( mhsize > DefaultMHSize ) { 46659599516SKenneth E. Jansen //if actual headersize is larger than default, let's re-read 46759599516SKenneth E. Jansen free(SerialFile->masterHeader); 46859599516SKenneth E. Jansen SerialFile->masterHeader = (char *)malloc(mhsize); 46959599516SKenneth E. Jansen fseek(fileHandle, 0, SEEK_SET); // reset the file stream position 47059599516SKenneth E. Jansen fread(SerialFile->masterHeader,1,mhsize,fileHandle); 47159599516SKenneth E. Jansen } 47259599516SKenneth E. Jansen } 47359599516SKenneth E. Jansen //TODO: check if this is a valid int?? 47459599516SKenneth E. Jansen MasterHeaderSize = mhsize; 47559599516SKenneth E. Jansen } 47659599516SKenneth E. Jansen else { // else it's version 0's format w/o version tag, implicating MHSize=4M 47759599516SKenneth E. Jansen MasterHeaderSize = DefaultMHSize; 47859599516SKenneth E. Jansen } 47959599516SKenneth E. Jansen 48059599516SKenneth E. Jansen memcpy( read_out_tag, 48159599516SKenneth E. Jansen SerialFile->masterHeader+MAX_FIELDS_NAME_LENGTH+1, 48259599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH ); //TODO: why +1 48359599516SKenneth E. Jansen 48459599516SKenneth E. Jansen // Read in # fields ... 48559599516SKenneth E. Jansen token = strtok( read_out_tag, ":" ); 48659599516SKenneth E. Jansen token = strtok( NULL," ,;<>" ); 48759599516SKenneth E. Jansen *nfields = atoi( token ); 48859599516SKenneth E. Jansen if ( *nfields > MAX_FIELDS_NUMBER) { 48959599516SKenneth E. Jansen printf("Error queryphmpiio: nfields is larger than MAX_FIELDS_NUMBER!\n"); 49059599516SKenneth E. Jansen } 49159599516SKenneth E. Jansen SerialFile->nfields=*nfields; //TODO: sanity check of this int? 49259599516SKenneth E. Jansen 49359599516SKenneth E. Jansen memcpy( read_out_tag, 49459599516SKenneth E. Jansen SerialFile->masterHeader + MAX_FIELDS_NAME_LENGTH * 2 49559599516SKenneth E. Jansen + *nfields * MAX_FIELDS_NAME_LENGTH, 49659599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH); 49759599516SKenneth E. Jansen 49859599516SKenneth E. Jansen token = strtok( read_out_tag, ":" ); 49959599516SKenneth E. Jansen token = strtok( NULL," ,;<>" ); 50059599516SKenneth E. Jansen *nppf = atoi( token ); 50159599516SKenneth E. Jansen SerialFile->nppf=*nppf; //TODO: sanity check of int 50259599516SKenneth E. Jansen } // end of if("MPI_IO_TAG") 50359599516SKenneth E. Jansen else { 50459599516SKenneth E. Jansen printf("Error queryphmpiio: The file you opened is not of syncIO new format, please check! read_out_tag = %s\n",read_out_tag); 50559599516SKenneth E. Jansen exit(1); 50659599516SKenneth E. Jansen } 50759599516SKenneth E. Jansen fclose(fileHandle); 50859599516SKenneth E. Jansen free(SerialFile->masterHeader); 50959599516SKenneth E. Jansen free(SerialFile); 51059599516SKenneth E. Jansen } //end of else 51159599516SKenneth E. Jansen free(fname); 51259599516SKenneth E. Jansen } 51359599516SKenneth E. Jansen 51459599516SKenneth E. Jansen // Bcast value to every one 51559599516SKenneth E. Jansen MPI_Bcast( nfields, 1, MPI_INT, 0, MPI_COMM_WORLD ); 51659599516SKenneth E. Jansen MPI_Bcast( nppf, 1, MPI_INT, 0, MPI_COMM_WORLD ); 51759599516SKenneth E. Jansen MPI_Bcast( &MasterHeaderSize, 1, MPI_INT, 0, MPI_COMM_WORLD ); 51859599516SKenneth E. Jansen phprintf("Info queryphmpiio: myrank = %d, MasterHeaderSize = %d", irank, MasterHeaderSize); 51959599516SKenneth E. Jansen } 52059599516SKenneth E. Jansen 52159599516SKenneth E. Jansen /** 52259599516SKenneth E. Jansen * This function computes the right master header size (round to size of 2^n). 52359599516SKenneth E. Jansen * This is only needed for file format version 1 in "write" mode. 52459599516SKenneth E. Jansen */ 52559599516SKenneth E. Jansen int computeMHSize(int nfields, int nppf, int version) { 52610d56689SCameron Smith int mhsize=0; 52759599516SKenneth E. Jansen if(version == 1) { 52859599516SKenneth E. Jansen //int meta_info_size = (2+nfields+1) * MAX_FIELDS_NAME_LENGTH; // 2 is MPI_IO_TAG and nFields, the others 1 is nppf 52959599516SKenneth E. Jansen int meta_info_size = VERSION_INFO_HEADER_SIZE; 5302dd307a1SCameron Smith int actual_size = nfields * nppf * sizeof(unsigned long) + meta_info_size; 53159599516SKenneth E. Jansen //printf("actual_size = %d, offset table size = %d\n", actual_size, nfields * nppf * sizeof(long long)); 53259599516SKenneth E. Jansen if (actual_size > DefaultMHSize) { 53359599516SKenneth E. Jansen mhsize = (int) ceil( (double) actual_size/DefaultMHSize); // it's rounded to ceiling of this value 53459599516SKenneth E. Jansen mhsize *= DefaultMHSize; 53559599516SKenneth E. Jansen } 53659599516SKenneth E. Jansen else { 53759599516SKenneth E. Jansen mhsize = DefaultMHSize; 53859599516SKenneth E. Jansen } 539b744cbcaSCameron Smith } else { 540b744cbcaSCameron Smith int rank = 0; 541b744cbcaSCameron Smith MPI_Comm_rank(MPI_COMM_WORLD, &rank); 542b744cbcaSCameron Smith if(!rank) { 543b744cbcaSCameron Smith fprintf(stderr, 544b744cbcaSCameron Smith "ERROR invalid version passed to %s... exiting\n", __func__); 545b744cbcaSCameron Smith exit(EXIT_FAILURE); 546b744cbcaSCameron Smith } 54759599516SKenneth E. Jansen } 54859599516SKenneth E. Jansen return mhsize; 54959599516SKenneth E. Jansen } 55059599516SKenneth E. Jansen 55159599516SKenneth E. Jansen /** 55259599516SKenneth E. Jansen * Computes correct color of a rank according to number of files. 55359599516SKenneth E. Jansen */ 55459599516SKenneth E. Jansen extern "C" int computeColor( int myrank, int numprocs, int nfiles) { 55559599516SKenneth E. Jansen int color = 55659599516SKenneth E. Jansen (int)(myrank / (numprocs / nfiles)); 55759599516SKenneth E. Jansen return color; 55859599516SKenneth E. Jansen } 55959599516SKenneth E. Jansen 56059599516SKenneth E. Jansen 56159599516SKenneth E. Jansen /** 56259599516SKenneth E. Jansen * Check the file descriptor. 56359599516SKenneth E. Jansen */ 56459599516SKenneth E. Jansen void checkFileDescriptor(const char fctname[], 56559599516SKenneth E. Jansen int* fileDescriptor ) { 56659599516SKenneth E. Jansen if ( *fileDescriptor < 0 ) { 56759599516SKenneth E. Jansen printf("Error: File descriptor = %d in %s\n",*fileDescriptor,fctname); 56859599516SKenneth E. Jansen exit(1); 56959599516SKenneth E. Jansen } 57059599516SKenneth E. Jansen } 57159599516SKenneth E. Jansen 57259599516SKenneth E. Jansen /** 57359599516SKenneth E. Jansen * Initialize the file struct members and allocate space for file struct 57459599516SKenneth E. Jansen * buffers. 57559599516SKenneth E. Jansen * 57659599516SKenneth E. Jansen * Note: this function is only called when we are using new format. Old POSIX 57759599516SKenneth E. Jansen * format should skip this routine and call openfile() directly instead. 57859599516SKenneth E. Jansen */ 57959599516SKenneth E. Jansen int initphmpiio( int *nfields, int *nppf, int *nfiles, int *filehandle, const char mode[]) 58059599516SKenneth E. Jansen { 58159599516SKenneth E. Jansen // we init irank again in case query not called (e.g. syncIO write case) 58259599516SKenneth E. Jansen MPI_Comm_rank(MPI_COMM_WORLD, &irank); 58359599516SKenneth E. Jansen MPI_Comm_size(MPI_COMM_WORLD, &mysize); 58459599516SKenneth E. Jansen 58559599516SKenneth E. Jansen phprintf("Info initphmpiio: entering function, myrank = %d, MasterHeaderSize = %d", irank, MasterHeaderSize); 58659599516SKenneth E. Jansen 58759599516SKenneth E. Jansen double timer_start, timer_end; 58859599516SKenneth E. Jansen startTimer(&timer_start); 58959599516SKenneth E. Jansen 59059599516SKenneth E. Jansen char* imode = StringStripper( mode ); 59159599516SKenneth E. Jansen 59259599516SKenneth E. Jansen // Note: if it's read, we presume query was called prior to init and 59359599516SKenneth E. Jansen // MasterHeaderSize is already set to correct value from parsing header 59459599516SKenneth E. Jansen // otherwise it's write then it needs some computation to be set 59559599516SKenneth E. Jansen if ( cscompare( "read", imode ) ) { 59659599516SKenneth E. Jansen // do nothing 59759599516SKenneth E. Jansen } 59859599516SKenneth E. Jansen else if( cscompare( "write", imode ) ) { 59959599516SKenneth E. Jansen MasterHeaderSize = computeMHSize(*nfields, *nppf, LATEST_WRITE_VERSION); 60059599516SKenneth E. Jansen } 60159599516SKenneth E. Jansen else { 60259599516SKenneth E. Jansen printf("Error initphmpiio: can't recognize the mode %s", imode); 60359599516SKenneth E. Jansen exit(1); 60459599516SKenneth E. Jansen } 60559599516SKenneth E. Jansen free ( imode ); 60659599516SKenneth E. Jansen 60759599516SKenneth E. Jansen phprintf("Info initphmpiio: myrank = %d, MasterHeaderSize = %d", irank, MasterHeaderSize); 60859599516SKenneth E. Jansen 60959599516SKenneth E. Jansen int i, j; 61059599516SKenneth E. Jansen 61159599516SKenneth E. Jansen if( PhastaIONextActiveIndex == MAX_PHASTA_FILES ) { 61259599516SKenneth E. Jansen printf("Error initphmpiio: PhastaIONextActiveIndex = MAX_PHASTA_FILES"); 61359599516SKenneth E. Jansen endTimer(&timer_end); 61459599516SKenneth E. Jansen printPerf("initphmpiio", timer_start, timer_end, 0, 0, ""); 61559599516SKenneth E. Jansen return MAX_PHASTA_FILES_EXCEEDED; 61659599516SKenneth E. Jansen } 61759599516SKenneth E. Jansen // else if( PhastaIONextActiveIndex == 0 ) //Hang in debug mode on Intrepid 61859599516SKenneth E. Jansen // { 61959599516SKenneth E. Jansen // for( i = 0; i < MAX_PHASTA_FILES; i++ ); 62059599516SKenneth E. Jansen // { 62159599516SKenneth E. Jansen // PhastaIOActiveFiles[i] = NULL; 62259599516SKenneth E. Jansen // } 62359599516SKenneth E. Jansen // } 62459599516SKenneth E. Jansen 62559599516SKenneth E. Jansen 62659599516SKenneth E. Jansen PhastaIOActiveFiles[PhastaIONextActiveIndex] = (phastaio_file_t *)calloc( 1, sizeof( phastaio_file_t) ); 62759599516SKenneth E. Jansen 62859599516SKenneth E. Jansen i = PhastaIONextActiveIndex; 62959599516SKenneth E. Jansen PhastaIONextActiveIndex++; 63059599516SKenneth E. Jansen 63159599516SKenneth E. Jansen //PhastaIOActiveFiles[i]->next_start_address = 2*TWO_MEGABYTE; 63259599516SKenneth E. Jansen 63359599516SKenneth E. Jansen PhastaIOActiveFiles[i]->next_start_address = MasterHeaderSize; // what does this mean??? TODO 63459599516SKenneth E. Jansen 63559599516SKenneth E. Jansen PhastaIOActiveFiles[i]->Wrong_Endian = false; 63659599516SKenneth E. Jansen 63759599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nFields = *nfields; 63859599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nPPF = *nppf; 63959599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nFiles = *nfiles; 64059599516SKenneth E. Jansen MPI_Comm_rank(MPI_COMM_WORLD, &(PhastaIOActiveFiles[i]->myrank)); 64159599516SKenneth E. Jansen MPI_Comm_size(MPI_COMM_WORLD, &(PhastaIOActiveFiles[i]->numprocs)); 64259599516SKenneth E. Jansen 64359599516SKenneth E. Jansen 64459599516SKenneth E. Jansen if( *nfiles > 1 ) { // split the ranks according to each mpiio file 64559599516SKenneth E. Jansen 64659599516SKenneth E. Jansen if ( s_assign_local_comm == 0) { // call mpi_comm_split for the first (and only) time 64759599516SKenneth E. Jansen 64859599516SKenneth E. Jansen if (PhastaIOActiveFiles[i]->myrank == 0) printf("Building subcommunicator\n"); 64959599516SKenneth E. Jansen 65059599516SKenneth E. Jansen int color = computeColor(PhastaIOActiveFiles[i]->myrank, PhastaIOActiveFiles[i]->numprocs, PhastaIOActiveFiles[i]->nFiles); 65159599516SKenneth E. Jansen MPI_Comm_split(MPI_COMM_WORLD, 65259599516SKenneth E. Jansen color, 65359599516SKenneth E. Jansen PhastaIOActiveFiles[i]->myrank, 65459599516SKenneth E. Jansen &(PhastaIOActiveFiles[i]->local_comm)); 65559599516SKenneth E. Jansen MPI_Comm_size(PhastaIOActiveFiles[i]->local_comm, 65659599516SKenneth E. Jansen &(PhastaIOActiveFiles[i]->local_numprocs)); 65759599516SKenneth E. Jansen MPI_Comm_rank(PhastaIOActiveFiles[i]->local_comm, 65859599516SKenneth E. Jansen &(PhastaIOActiveFiles[i]->local_myrank)); 65959599516SKenneth E. Jansen 66059599516SKenneth E. Jansen // back up now these variables so that we do not need to call comm_split again 66159599516SKenneth E. Jansen s_local_comm = PhastaIOActiveFiles[i]->local_comm; 66259599516SKenneth E. Jansen s_local_size = PhastaIOActiveFiles[i]->local_numprocs; 66359599516SKenneth E. Jansen s_local_rank = PhastaIOActiveFiles[i]->local_myrank; 66459599516SKenneth E. Jansen s_assign_local_comm = 1; 66559599516SKenneth E. Jansen } 66659599516SKenneth E. Jansen else { // recycle the subcommunicator 66759599516SKenneth E. Jansen if (PhastaIOActiveFiles[i]->myrank == 0) printf("Recycling subcommunicator\n"); 66859599516SKenneth E. Jansen PhastaIOActiveFiles[i]->local_comm = s_local_comm; 66959599516SKenneth E. Jansen PhastaIOActiveFiles[i]->local_numprocs = s_local_size; 67059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->local_myrank = s_local_rank; 67159599516SKenneth E. Jansen } 67259599516SKenneth E. Jansen } 67359599516SKenneth E. Jansen else { // *nfiles == 1 here - no need to call mpi_comm_split here 67459599516SKenneth E. Jansen 67559599516SKenneth E. Jansen if (PhastaIOActiveFiles[i]->myrank == 0) printf("Bypassing subcommunicator\n"); 67659599516SKenneth E. Jansen PhastaIOActiveFiles[i]->local_comm = MPI_COMM_WORLD; 67759599516SKenneth E. Jansen PhastaIOActiveFiles[i]->local_numprocs = PhastaIOActiveFiles[i]->numprocs; 67859599516SKenneth E. Jansen PhastaIOActiveFiles[i]->local_myrank = PhastaIOActiveFiles[i]->myrank; 67959599516SKenneth E. Jansen 68059599516SKenneth E. Jansen } 68159599516SKenneth E. Jansen 68259599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nppp = 68359599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nPPF/PhastaIOActiveFiles[i]->local_numprocs; 68459599516SKenneth E. Jansen 68559599516SKenneth E. Jansen PhastaIOActiveFiles[i]->start_id = PhastaIOActiveFiles[i]->nPPF * 68659599516SKenneth E. Jansen (int)(PhastaIOActiveFiles[i]->myrank/PhastaIOActiveFiles[i]->local_numprocs) + 68759599516SKenneth E. Jansen (PhastaIOActiveFiles[i]->local_myrank * PhastaIOActiveFiles[i]->nppp); 68859599516SKenneth E. Jansen 68959599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_offset_table = 6902dd307a1SCameron Smith ( unsigned long ** ) calloc( MAX_FIELDS_NUMBER , sizeof( unsigned long *) ); 69159599516SKenneth E. Jansen 69259599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_read_table = 6932dd307a1SCameron Smith ( unsigned long ** ) calloc( MAX_FIELDS_NUMBER , sizeof( unsigned long *) ); 69459599516SKenneth E. Jansen 69559599516SKenneth E. Jansen for (j=0; j<*nfields; j++) 69659599516SKenneth E. Jansen { 69759599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_offset_table[j] = 6982dd307a1SCameron Smith ( unsigned long * ) calloc( PhastaIOActiveFiles[i]->nppp , sizeof( unsigned long) ); 69959599516SKenneth E. Jansen 70059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_read_table[j] = 7012dd307a1SCameron Smith ( unsigned long * ) calloc( PhastaIOActiveFiles[i]->nppp , sizeof( unsigned long) ); 70259599516SKenneth E. Jansen } 70359599516SKenneth E. Jansen *filehandle = i; 70459599516SKenneth E. Jansen 70559599516SKenneth E. Jansen PhastaIOActiveFiles[i]->master_header = (char *)calloc(MasterHeaderSize,sizeof( char )); 70659599516SKenneth E. Jansen PhastaIOActiveFiles[i]->double_chunk = (double *)calloc(1,sizeof( double )); 70759599516SKenneth E. Jansen PhastaIOActiveFiles[i]->int_chunk = (int *)calloc(1,sizeof( int )); 70859599516SKenneth E. Jansen PhastaIOActiveFiles[i]->read_double_chunk = (double *)calloc(1,sizeof( double )); 70959599516SKenneth E. Jansen PhastaIOActiveFiles[i]->read_int_chunk = (int *)calloc(1,sizeof( int )); 71059599516SKenneth E. Jansen 71159599516SKenneth E. Jansen // Time monitoring 71259599516SKenneth E. Jansen endTimer(&timer_end); 71359599516SKenneth E. Jansen printPerf("initphmpiio", timer_start, timer_end, 0, 0, ""); 71459599516SKenneth E. Jansen 71559599516SKenneth E. Jansen phprintf_0("Info initphmpiio: quiting function"); 71659599516SKenneth E. Jansen 71759599516SKenneth E. Jansen return i; 71859599516SKenneth E. Jansen } 71959599516SKenneth E. Jansen 72059599516SKenneth E. Jansen /** 72159599516SKenneth E. Jansen * Destruct the file struct and free buffers allocated in init function. 72259599516SKenneth E. Jansen */ 72359599516SKenneth E. Jansen void finalizephmpiio( int *fileDescriptor ) 72459599516SKenneth E. Jansen { 72559599516SKenneth E. Jansen double timer_start, timer_end; 72659599516SKenneth E. Jansen startTimer(&timer_start); 72759599516SKenneth E. Jansen 72859599516SKenneth E. Jansen int i, j; 72959599516SKenneth E. Jansen i = *fileDescriptor; 73059599516SKenneth E. Jansen //PhastaIONextActiveIndex--; 73159599516SKenneth E. Jansen 73259599516SKenneth E. Jansen /* //free the offset table for this phasta file */ 73359599516SKenneth E. Jansen //for(j=0; j<MAX_FIELDS_NUMBER; j++) //Danger: undefined behavior for my_*_table.[j] not allocated or not initialized to NULL 73459599516SKenneth E. Jansen for(j=0; j<PhastaIOActiveFiles[i]->nFields; j++) 73559599516SKenneth E. Jansen { 73659599516SKenneth E. Jansen free( PhastaIOActiveFiles[i]->my_offset_table[j]); 73759599516SKenneth E. Jansen free( PhastaIOActiveFiles[i]->my_read_table[j]); 73859599516SKenneth E. Jansen } 73959599516SKenneth E. Jansen free ( PhastaIOActiveFiles[i]->my_offset_table ); 74059599516SKenneth E. Jansen free ( PhastaIOActiveFiles[i]->my_read_table ); 74159599516SKenneth E. Jansen free ( PhastaIOActiveFiles[i]->master_header ); 74259599516SKenneth E. Jansen free ( PhastaIOActiveFiles[i]->double_chunk ); 74359599516SKenneth E. Jansen free ( PhastaIOActiveFiles[i]->int_chunk ); 74459599516SKenneth E. Jansen free ( PhastaIOActiveFiles[i]->read_double_chunk ); 74559599516SKenneth E. Jansen free ( PhastaIOActiveFiles[i]->read_int_chunk ); 74659599516SKenneth E. Jansen 747946a6cddSCameron Smith if( PhastaIOActiveFiles[i]->nFiles > 1 && s_assign_local_comm ) { // the comm was split 748946a6cddSCameron Smith if (PhastaIOActiveFiles[i]->myrank == 0) printf("Freeing subcommunicator\n"); 749946a6cddSCameron Smith s_assign_local_comm = 0; 750946a6cddSCameron Smith MPI_Comm_free(&(PhastaIOActiveFiles[i]->local_comm)); 751946a6cddSCameron Smith } 752946a6cddSCameron Smith 75359599516SKenneth E. Jansen free( PhastaIOActiveFiles[i]); 75459599516SKenneth E. Jansen 75559599516SKenneth E. Jansen endTimer(&timer_end); 75659599516SKenneth E. Jansen printPerf("finalizempiio", timer_start, timer_end, 0, 0, ""); 75759599516SKenneth E. Jansen 75859599516SKenneth E. Jansen PhastaIONextActiveIndex--; 75959599516SKenneth E. Jansen } 76059599516SKenneth E. Jansen 76159599516SKenneth E. Jansen 76259599516SKenneth E. Jansen /** 76359599516SKenneth E. Jansen * Special init for M2N in order to create a subcommunicator for the reduced solution (requires PRINT_PERF to be false for now) 76459599516SKenneth E. Jansen * Initialize the file struct members and allocate space for file struct buffers. 76559599516SKenneth E. Jansen * 76659599516SKenneth E. Jansen * Note: this function is only called when we are using new format. Old POSIX 76759599516SKenneth E. Jansen * format should skip this routine and call openfile() directly instead. 76859599516SKenneth E. Jansen */ 76959599516SKenneth E. Jansen int initphmpiiosub( int *nfields, int *nppf, int *nfiles, int *filehandle, const char mode[],MPI_Comm my_local_comm) 77059599516SKenneth E. Jansen { 77159599516SKenneth E. Jansen // we init irank again in case query not called (e.g. syncIO write case) 77259599516SKenneth E. Jansen 77359599516SKenneth E. Jansen MPI_Comm_rank(my_local_comm, &irank); 77459599516SKenneth E. Jansen MPI_Comm_size(my_local_comm, &mysize); 77559599516SKenneth E. Jansen 77659599516SKenneth E. Jansen phprintf("Info initphmpiio: entering function, myrank = %d, MasterHeaderSize = %d", irank, MasterHeaderSize); 77759599516SKenneth E. Jansen 77859599516SKenneth E. Jansen double timer_start, timer_end; 77959599516SKenneth E. Jansen startTimer(&timer_start); 78059599516SKenneth E. Jansen 78159599516SKenneth E. Jansen char* imode = StringStripper( mode ); 78259599516SKenneth E. Jansen 78359599516SKenneth E. Jansen // Note: if it's read, we presume query was called prior to init and 78459599516SKenneth E. Jansen // MasterHeaderSize is already set to correct value from parsing header 78559599516SKenneth E. Jansen // otherwise it's write then it needs some computation to be set 78659599516SKenneth E. Jansen if ( cscompare( "read", imode ) ) { 78759599516SKenneth E. Jansen // do nothing 78859599516SKenneth E. Jansen } 78959599516SKenneth E. Jansen else if( cscompare( "write", imode ) ) { 79059599516SKenneth E. Jansen MasterHeaderSize = computeMHSize(*nfields, *nppf, LATEST_WRITE_VERSION); 79159599516SKenneth E. Jansen } 79259599516SKenneth E. Jansen else { 79359599516SKenneth E. Jansen printf("Error initphmpiio: can't recognize the mode %s", imode); 79459599516SKenneth E. Jansen exit(1); 79559599516SKenneth E. Jansen } 79659599516SKenneth E. Jansen free ( imode ); 79759599516SKenneth E. Jansen 79859599516SKenneth E. Jansen phprintf("Info initphmpiio: myrank = %d, MasterHeaderSize = %d", irank, MasterHeaderSize); 79959599516SKenneth E. Jansen 80059599516SKenneth E. Jansen int i, j; 80159599516SKenneth E. Jansen 80259599516SKenneth E. Jansen if( PhastaIONextActiveIndex == MAX_PHASTA_FILES ) { 80359599516SKenneth E. Jansen printf("Error initphmpiio: PhastaIONextActiveIndex = MAX_PHASTA_FILES"); 80459599516SKenneth E. Jansen endTimer(&timer_end); 80559599516SKenneth E. Jansen printPerf("initphmpiio", timer_start, timer_end, 0, 0, ""); 80659599516SKenneth E. Jansen return MAX_PHASTA_FILES_EXCEEDED; 80759599516SKenneth E. Jansen } 80859599516SKenneth E. Jansen // else if( PhastaIONextActiveIndex == 0 ) //Hang in debug mode on Intrepid 80959599516SKenneth E. Jansen // { 81059599516SKenneth E. Jansen // for( i = 0; i < MAX_PHASTA_FILES; i++ ); 81159599516SKenneth E. Jansen // { 81259599516SKenneth E. Jansen // PhastaIOActiveFiles[i] = NULL; 81359599516SKenneth E. Jansen // } 81459599516SKenneth E. Jansen // } 81559599516SKenneth E. Jansen 81659599516SKenneth E. Jansen 81759599516SKenneth E. Jansen PhastaIOActiveFiles[PhastaIONextActiveIndex] = (phastaio_file_t *)calloc( 1, sizeof( phastaio_file_t) ); 81859599516SKenneth E. Jansen 81959599516SKenneth E. Jansen i = PhastaIONextActiveIndex; 82059599516SKenneth E. Jansen PhastaIONextActiveIndex++; 82159599516SKenneth E. Jansen 82259599516SKenneth E. Jansen //PhastaIOActiveFiles[i]->next_start_address = 2*TWO_MEGABYTE; 82359599516SKenneth E. Jansen 82459599516SKenneth E. Jansen PhastaIOActiveFiles[i]->next_start_address = MasterHeaderSize; // what does this mean??? TODO 82559599516SKenneth E. Jansen 82659599516SKenneth E. Jansen PhastaIOActiveFiles[i]->Wrong_Endian = false; 82759599516SKenneth E. Jansen 82859599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nFields = *nfields; 82959599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nPPF = *nppf; 83059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nFiles = *nfiles; 83159599516SKenneth E. Jansen MPI_Comm_rank(my_local_comm, &(PhastaIOActiveFiles[i]->myrank)); 83259599516SKenneth E. Jansen MPI_Comm_size(my_local_comm, &(PhastaIOActiveFiles[i]->numprocs)); 83359599516SKenneth E. Jansen 83459599516SKenneth E. Jansen int color = computeColor(PhastaIOActiveFiles[i]->myrank, PhastaIOActiveFiles[i]->numprocs, PhastaIOActiveFiles[i]->nFiles); 83559599516SKenneth E. Jansen MPI_Comm_split(my_local_comm, 83659599516SKenneth E. Jansen color, 83759599516SKenneth E. Jansen PhastaIOActiveFiles[i]->myrank, 83859599516SKenneth E. Jansen &(PhastaIOActiveFiles[i]->local_comm)); 83959599516SKenneth E. Jansen MPI_Comm_size(PhastaIOActiveFiles[i]->local_comm, 84059599516SKenneth E. Jansen &(PhastaIOActiveFiles[i]->local_numprocs)); 84159599516SKenneth E. Jansen MPI_Comm_rank(PhastaIOActiveFiles[i]->local_comm, 84259599516SKenneth E. Jansen &(PhastaIOActiveFiles[i]->local_myrank)); 84359599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nppp = 84459599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nPPF/PhastaIOActiveFiles[i]->local_numprocs; 84559599516SKenneth E. Jansen 84659599516SKenneth E. Jansen PhastaIOActiveFiles[i]->start_id = PhastaIOActiveFiles[i]->nPPF * 84759599516SKenneth E. Jansen (int)(PhastaIOActiveFiles[i]->myrank/PhastaIOActiveFiles[i]->local_numprocs) + 84859599516SKenneth E. Jansen (PhastaIOActiveFiles[i]->local_myrank * PhastaIOActiveFiles[i]->nppp); 84959599516SKenneth E. Jansen 85059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_offset_table = 8512dd307a1SCameron Smith ( unsigned long ** ) calloc( MAX_FIELDS_NUMBER , sizeof( unsigned long *) ); 85259599516SKenneth E. Jansen 85359599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_read_table = 8542dd307a1SCameron Smith ( unsigned long ** ) calloc( MAX_FIELDS_NUMBER , sizeof( unsigned long *) ); 85559599516SKenneth E. Jansen 85659599516SKenneth E. Jansen for (j=0; j<*nfields; j++) 85759599516SKenneth E. Jansen { 85859599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_offset_table[j] = 8592dd307a1SCameron Smith ( unsigned long * ) calloc( PhastaIOActiveFiles[i]->nppp , sizeof( unsigned long) ); 86059599516SKenneth E. Jansen 86159599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_read_table[j] = 8622dd307a1SCameron Smith ( unsigned long * ) calloc( PhastaIOActiveFiles[i]->nppp , sizeof( unsigned long) ); 86359599516SKenneth E. Jansen } 86459599516SKenneth E. Jansen *filehandle = i; 86559599516SKenneth E. Jansen 86659599516SKenneth E. Jansen PhastaIOActiveFiles[i]->master_header = (char *)calloc(MasterHeaderSize,sizeof( char )); 86759599516SKenneth E. Jansen PhastaIOActiveFiles[i]->double_chunk = (double *)calloc(1,sizeof( double )); 86859599516SKenneth E. Jansen PhastaIOActiveFiles[i]->int_chunk = (int *)calloc(1,sizeof( int )); 86959599516SKenneth E. Jansen PhastaIOActiveFiles[i]->read_double_chunk = (double *)calloc(1,sizeof( double )); 87059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->read_int_chunk = (int *)calloc(1,sizeof( int )); 87159599516SKenneth E. Jansen 87259599516SKenneth E. Jansen // Time monitoring 87359599516SKenneth E. Jansen endTimer(&timer_end); 87459599516SKenneth E. Jansen printPerf("initphmpiiosub", timer_start, timer_end, 0, 0, ""); 87559599516SKenneth E. Jansen 87659599516SKenneth E. Jansen phprintf_0("Info initphmpiiosub: quiting function"); 87759599516SKenneth E. Jansen 87859599516SKenneth E. Jansen return i; 87959599516SKenneth E. Jansen } 88059599516SKenneth E. Jansen 88159599516SKenneth E. Jansen 88259599516SKenneth E. Jansen 88359599516SKenneth E. Jansen /** open file for both POSIX and MPI-IO syncIO format. 88459599516SKenneth E. Jansen * 88559599516SKenneth E. Jansen * If it's old POSIX format, simply call posix fopen(). 88659599516SKenneth E. Jansen * 88759599516SKenneth E. Jansen * If it's MPI-IO foramt: 88859599516SKenneth E. Jansen * in "read" mode, it builds the header table that points to the offset of 88959599516SKenneth E. Jansen * fields for parts; 89059599516SKenneth E. Jansen * in "write" mode, it opens the file with MPI-IO open routine. 89159599516SKenneth E. Jansen */ 89259599516SKenneth E. Jansen void openfile(const char filename[], 89359599516SKenneth E. Jansen const char mode[], 89459599516SKenneth E. Jansen int* fileDescriptor ) 89559599516SKenneth E. Jansen { 89659599516SKenneth E. Jansen phprintf_0("Info: entering openfile"); 89759599516SKenneth E. Jansen 89859599516SKenneth E. Jansen double timer_start, timer_end; 89959599516SKenneth E. Jansen startTimer(&timer_start); 90059599516SKenneth E. Jansen 90159599516SKenneth E. Jansen if ( PhastaIONextActiveIndex == 0 ) 90259599516SKenneth E. Jansen { 90359599516SKenneth E. Jansen FILE* file=NULL ; 90459599516SKenneth E. Jansen *fileDescriptor = 0; 90559599516SKenneth E. Jansen char* fname = StringStripper( filename ); 90659599516SKenneth E. Jansen char* imode = StringStripper( mode ); 90759599516SKenneth E. Jansen 90859599516SKenneth E. Jansen if ( cscompare( "read", imode ) ) file = fopen(fname, "rb" ); 90959599516SKenneth E. Jansen else if( cscompare( "write", imode ) ) file = fopen(fname, "wb" ); 91059599516SKenneth E. Jansen else if( cscompare( "append", imode ) ) file = fopen(fname, "ab" ); 91159599516SKenneth E. Jansen 91259599516SKenneth E. Jansen if ( !file ){ 91359599516SKenneth E. Jansen fprintf(stderr,"Error openfile: unable to open file %s",fname ) ; 91459599516SKenneth E. Jansen } else { 91559599516SKenneth E. Jansen fileArray.push_back( file ); 91659599516SKenneth E. Jansen byte_order.push_back( false ); 91759599516SKenneth E. Jansen header_type.push_back( sizeof(int) ); 91859599516SKenneth E. Jansen *fileDescriptor = fileArray.size(); 91959599516SKenneth E. Jansen } 92059599516SKenneth E. Jansen free (fname); 92159599516SKenneth E. Jansen free (imode); 92259599516SKenneth E. Jansen } 92359599516SKenneth E. Jansen else // else it would be parallel I/O, opposed to posix io 92459599516SKenneth E. Jansen { 92559599516SKenneth E. Jansen char* fname = StringStripper( filename ); 92659599516SKenneth E. Jansen char* imode = StringStripper( mode ); 92759599516SKenneth E. Jansen int rc; 92859599516SKenneth E. Jansen int i = *fileDescriptor; 92959599516SKenneth E. Jansen checkFileDescriptor("openfile",&i); 93059599516SKenneth E. Jansen char* token; 93159599516SKenneth E. Jansen 93259599516SKenneth E. Jansen if ( cscompare( "read", imode ) ) 93359599516SKenneth E. Jansen { 93459599516SKenneth E. Jansen // if (PhastaIOActiveFiles[i]->myrank == 0) 93559599516SKenneth E. Jansen // printf("\n **********\nRead open ... ... regular version\n"); 93659599516SKenneth E. Jansen 93759599516SKenneth E. Jansen rc = MPI_File_open( PhastaIOActiveFiles[i]->local_comm, 93859599516SKenneth E. Jansen fname, 93959599516SKenneth E. Jansen MPI_MODE_RDONLY, 94059599516SKenneth E. Jansen MPI_INFO_NULL, 94159599516SKenneth E. Jansen &(PhastaIOActiveFiles[i]->file_handle) ); 94259599516SKenneth E. Jansen 94359599516SKenneth E. Jansen if(rc) 94459599516SKenneth E. Jansen { 94559599516SKenneth E. Jansen *fileDescriptor = UNABLE_TO_OPEN_FILE; 94659599516SKenneth E. Jansen printf("Error openfile: Unable to open file %s! File descriptor = %d\n",fname,*fileDescriptor); 94759599516SKenneth E. Jansen endTimer(&timer_end); 94859599516SKenneth E. Jansen printPerf("openfile", timer_start, timer_end, 0, 0, ""); 94959599516SKenneth E. Jansen return; 95059599516SKenneth E. Jansen } 95159599516SKenneth E. Jansen 95259599516SKenneth E. Jansen MPI_Status read_tag_status; 95359599516SKenneth E. Jansen char read_out_tag[MAX_FIELDS_NAME_LENGTH]; 95459599516SKenneth E. Jansen int j; 95559599516SKenneth E. Jansen int magic_number; 95659599516SKenneth E. Jansen 95759599516SKenneth E. Jansen if ( PhastaIOActiveFiles[i]->local_myrank == 0 ) { 95859599516SKenneth E. Jansen MPI_File_read_at( PhastaIOActiveFiles[i]->file_handle, 95959599516SKenneth E. Jansen 0, 96059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->master_header, 96159599516SKenneth E. Jansen MasterHeaderSize, 96259599516SKenneth E. Jansen MPI_CHAR, 96359599516SKenneth E. Jansen &read_tag_status ); 96459599516SKenneth E. Jansen } 96559599516SKenneth E. Jansen 96659599516SKenneth E. Jansen MPI_Bcast( PhastaIOActiveFiles[i]->master_header, 96759599516SKenneth E. Jansen MasterHeaderSize, 96859599516SKenneth E. Jansen MPI_CHAR, 96959599516SKenneth E. Jansen 0, 97059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->local_comm ); 97159599516SKenneth E. Jansen 97259599516SKenneth E. Jansen memcpy( read_out_tag, 97359599516SKenneth E. Jansen PhastaIOActiveFiles[i]->master_header, 97459599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH-1 ); 97559599516SKenneth E. Jansen 97659599516SKenneth E. Jansen if ( cscompare ("MPI_IO_Tag",read_out_tag) ) 97759599516SKenneth E. Jansen { 97859599516SKenneth E. Jansen // Test endianess ... 97959599516SKenneth E. Jansen memcpy ( &magic_number, 98059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->master_header+sizeof("MPI_IO_Tag : ")-1, //-1 sizeof returns the size of the string+1 for "\0" 98159599516SKenneth E. Jansen sizeof(int) ); // masterheader should look like "MPI_IO_Tag : 12180 " with 12180 in binary format 98259599516SKenneth E. Jansen 98359599516SKenneth E. Jansen if ( magic_number != ENDIAN_TEST_NUMBER ) 98459599516SKenneth E. Jansen { 98559599516SKenneth E. Jansen PhastaIOActiveFiles[i]->Wrong_Endian = true; 98659599516SKenneth E. Jansen } 98759599516SKenneth E. Jansen 98859599516SKenneth E. Jansen memcpy( read_out_tag, 98959599516SKenneth E. Jansen PhastaIOActiveFiles[i]->master_header+MAX_FIELDS_NAME_LENGTH+1, // TODO: WHY +1??? 99059599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH ); 99159599516SKenneth E. Jansen 99259599516SKenneth E. Jansen // Read in # fields ... 99359599516SKenneth E. Jansen token = strtok ( read_out_tag, ":" ); 99459599516SKenneth E. Jansen token = strtok( NULL," ,;<>" ); 99559599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nFields = atoi( token ); 99659599516SKenneth E. Jansen 9972dd307a1SCameron Smith unsigned long **header_table; 9982dd307a1SCameron Smith header_table = ( unsigned long ** )calloc(PhastaIOActiveFiles[i]->nFields, sizeof(unsigned long *)); 99959599516SKenneth E. Jansen 100059599516SKenneth E. Jansen for ( j = 0; j < PhastaIOActiveFiles[i]->nFields; j++ ) 100159599516SKenneth E. Jansen { 10022dd307a1SCameron Smith header_table[j]=( unsigned long * ) calloc( PhastaIOActiveFiles[i]->nPPF , sizeof( unsigned long)); 100359599516SKenneth E. Jansen } 100459599516SKenneth E. Jansen 100559599516SKenneth E. Jansen // Read in the offset table ... 100659599516SKenneth E. Jansen for ( j = 0; j < PhastaIOActiveFiles[i]->nFields; j++ ) 100759599516SKenneth E. Jansen { 100859599516SKenneth E. Jansen if ( PhastaIOActiveFiles[i]->local_myrank == 0 ) { 100959599516SKenneth E. Jansen memcpy( header_table[j], 101059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->master_header + 101159599516SKenneth E. Jansen VERSION_INFO_HEADER_SIZE + 10122dd307a1SCameron Smith j * PhastaIOActiveFiles[i]->nPPF * sizeof(unsigned long), 10132dd307a1SCameron Smith PhastaIOActiveFiles[i]->nPPF * sizeof(unsigned long) ); 101459599516SKenneth E. Jansen } 101559599516SKenneth E. Jansen 101659599516SKenneth E. Jansen MPI_Scatter( header_table[j], 101759599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nppp, 101859599516SKenneth E. Jansen MPI_LONG_LONG_INT, 101959599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_read_table[j], 102059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nppp, 102159599516SKenneth E. Jansen MPI_LONG_LONG_INT, 102259599516SKenneth E. Jansen 0, 102359599516SKenneth E. Jansen PhastaIOActiveFiles[i]->local_comm ); 102459599516SKenneth E. Jansen 102559599516SKenneth E. Jansen // Swap byte order if endianess is different ... 102659599516SKenneth E. Jansen if ( PhastaIOActiveFiles[i]->Wrong_Endian ) { 102759599516SKenneth E. Jansen SwapArrayByteOrder( PhastaIOActiveFiles[i]->my_read_table[j], 10284187599aSCameron Smith sizeof(unsigned long), 102959599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nppp ); 103059599516SKenneth E. Jansen } 103159599516SKenneth E. Jansen } 103259599516SKenneth E. Jansen 103359599516SKenneth E. Jansen for ( j = 0; j < PhastaIOActiveFiles[i]->nFields; j++ ) { 103459599516SKenneth E. Jansen free ( header_table[j] ); 103559599516SKenneth E. Jansen } 103659599516SKenneth E. Jansen free (header_table); 103759599516SKenneth E. Jansen 103859599516SKenneth E. Jansen } // end of if MPI_IO_TAG 103959599516SKenneth E. Jansen else //else not valid MPI file 104059599516SKenneth E. Jansen { 104159599516SKenneth E. Jansen *fileDescriptor = NOT_A_MPI_FILE; 104259599516SKenneth E. Jansen printf("Error openfile: The file %s you opened is not in syncIO new format, please check again! File descriptor = %d, MasterHeaderSize = %d, read_out_tag = %s\n",fname,*fileDescriptor,MasterHeaderSize,read_out_tag); 104359599516SKenneth E. Jansen //Printing MasterHeaderSize is useful to test a compiler bug on Intrepid BGP 104459599516SKenneth E. Jansen endTimer(&timer_end); 104559599516SKenneth E. Jansen printPerf("openfile", timer_start, timer_end, 0, 0, ""); 104659599516SKenneth E. Jansen return; 104759599516SKenneth E. Jansen } 104859599516SKenneth E. Jansen } // end of if "read" 104959599516SKenneth E. Jansen else if( cscompare( "write", imode ) ) 105059599516SKenneth E. Jansen { 105159599516SKenneth E. Jansen rc = MPI_File_open( PhastaIOActiveFiles[i]->local_comm, 105259599516SKenneth E. Jansen fname, 105359599516SKenneth E. Jansen MPI_MODE_WRONLY | MPI_MODE_CREATE, 105459599516SKenneth E. Jansen MPI_INFO_NULL, 105559599516SKenneth E. Jansen &(PhastaIOActiveFiles[i]->file_handle) ); 105659599516SKenneth E. Jansen if(rc) 105759599516SKenneth E. Jansen { 105859599516SKenneth E. Jansen *fileDescriptor = UNABLE_TO_OPEN_FILE; 105959599516SKenneth E. Jansen return; 106059599516SKenneth E. Jansen } 106159599516SKenneth E. Jansen } // end of if "write" 106259599516SKenneth E. Jansen free (fname); 106359599516SKenneth E. Jansen free (imode); 106459599516SKenneth E. Jansen } // end of if FileIndex != 0 106559599516SKenneth E. Jansen 106659599516SKenneth E. Jansen endTimer(&timer_end); 106759599516SKenneth E. Jansen printPerf("openfile", timer_start, timer_end, 0, 0, ""); 106859599516SKenneth E. Jansen } 106959599516SKenneth E. Jansen 107059599516SKenneth E. Jansen /** close file for both POSIX and MPI-IO syncIO format. 107159599516SKenneth E. Jansen * 107259599516SKenneth E. Jansen * If it's old POSIX format, simply call posix fclose(). 107359599516SKenneth E. Jansen * 107459599516SKenneth E. Jansen * If it's MPI-IO foramt: 107559599516SKenneth E. Jansen * in "read" mode, it simply close file with MPI-IO close routine. 107659599516SKenneth E. Jansen * in "write" mode, rank 0 in each group will re-assemble the master header and 107759599516SKenneth E. Jansen * offset table and write to the beginning of file, then close the file. 107859599516SKenneth E. Jansen */ 107959599516SKenneth E. Jansen void closefile( int* fileDescriptor, 108059599516SKenneth E. Jansen const char mode[] ) 108159599516SKenneth E. Jansen { 108259599516SKenneth E. Jansen double timer_start, timer_end; 108359599516SKenneth E. Jansen startTimer(&timer_start); 108459599516SKenneth E. Jansen 108559599516SKenneth E. Jansen int i = *fileDescriptor; 108659599516SKenneth E. Jansen checkFileDescriptor("closefile",&i); 108759599516SKenneth E. Jansen 108859599516SKenneth E. Jansen if ( PhastaIONextActiveIndex == 0 ) { 108959599516SKenneth E. Jansen char* imode = StringStripper( mode ); 109059599516SKenneth E. Jansen 109159599516SKenneth E. Jansen if( cscompare( "write", imode ) 109259599516SKenneth E. Jansen || cscompare( "append", imode ) ) { 109359599516SKenneth E. Jansen fflush( fileArray[ *fileDescriptor - 1 ] ); 109459599516SKenneth E. Jansen } 109559599516SKenneth E. Jansen 109659599516SKenneth E. Jansen fclose( fileArray[ *fileDescriptor - 1 ] ); 109759599516SKenneth E. Jansen free (imode); 109859599516SKenneth E. Jansen } 109959599516SKenneth E. Jansen else { 110059599516SKenneth E. Jansen char* imode = StringStripper( mode ); 110159599516SKenneth E. Jansen 110259599516SKenneth E. Jansen //write master header here: 110359599516SKenneth E. Jansen if ( cscompare( "write", imode ) ) { 110459599516SKenneth E. Jansen // if ( PhastaIOActiveFiles[i]->nPPF * PhastaIOActiveFiles[i]->nFields < 2*ONE_MEGABYTE/8 ) //SHOULD BE CHECKED 110559599516SKenneth E. Jansen // MasterHeaderSize = 4*ONE_MEGABYTE; 110659599516SKenneth E. Jansen // else 110759599516SKenneth E. Jansen // MasterHeaderSize = 4*ONE_MEGABYTE + PhastaIOActiveFiles[i]->nPPF * PhastaIOActiveFiles[i]->nFields * 8 - 2*ONE_MEGABYTE; 110859599516SKenneth E. Jansen 110959599516SKenneth E. Jansen MasterHeaderSize = computeMHSize( PhastaIOActiveFiles[i]->nFields, PhastaIOActiveFiles[i]->nPPF, LATEST_WRITE_VERSION); 111059599516SKenneth E. Jansen phprintf_0("Info closefile: myrank = %d, MasterHeaderSize = %d\n", PhastaIOActiveFiles[i]->myrank, MasterHeaderSize); 111159599516SKenneth E. Jansen 111259599516SKenneth E. Jansen MPI_Status write_header_status; 111359599516SKenneth E. Jansen char mpi_tag[MAX_FIELDS_NAME_LENGTH]; 111459599516SKenneth E. Jansen char version[MAX_FIELDS_NAME_LENGTH/4]; 111559599516SKenneth E. Jansen char mhsize[MAX_FIELDS_NAME_LENGTH/4]; 111659599516SKenneth E. Jansen int magic_number = ENDIAN_TEST_NUMBER; 111759599516SKenneth E. Jansen 111859599516SKenneth E. Jansen if ( PhastaIOActiveFiles[i]->local_myrank == 0 ) 111959599516SKenneth E. Jansen { 112059599516SKenneth E. Jansen bzero((void*)mpi_tag,MAX_FIELDS_NAME_LENGTH); 112159599516SKenneth E. Jansen sprintf(mpi_tag, "MPI_IO_Tag : "); 112259599516SKenneth E. Jansen memcpy(PhastaIOActiveFiles[i]->master_header, 112359599516SKenneth E. Jansen mpi_tag, 112459599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH); 112559599516SKenneth E. Jansen 112659599516SKenneth E. Jansen bzero((void*)version,MAX_FIELDS_NAME_LENGTH/4); 112759599516SKenneth E. Jansen // this version is "1", print version in ASCII 112859599516SKenneth E. Jansen sprintf(version, "version : %d",1); 112959599516SKenneth E. Jansen memcpy(PhastaIOActiveFiles[i]->master_header + MAX_FIELDS_NAME_LENGTH/2, 113059599516SKenneth E. Jansen version, 113159599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH/4); 113259599516SKenneth E. Jansen 113359599516SKenneth E. Jansen // master header size is computed using the formula above 113459599516SKenneth E. Jansen bzero((void*)mhsize,MAX_FIELDS_NAME_LENGTH/4); 113559599516SKenneth E. Jansen sprintf(mhsize, "mhsize : "); 113659599516SKenneth E. Jansen memcpy(PhastaIOActiveFiles[i]->master_header + MAX_FIELDS_NAME_LENGTH/4*3, 113759599516SKenneth E. Jansen mhsize, 113859599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH/4); 113959599516SKenneth E. Jansen 114059599516SKenneth E. Jansen bzero((void*)mpi_tag,MAX_FIELDS_NAME_LENGTH); 114159599516SKenneth E. Jansen sprintf(mpi_tag, 114259599516SKenneth E. Jansen "\nnFields : %d\n", 114359599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nFields); 114459599516SKenneth E. Jansen memcpy(PhastaIOActiveFiles[i]->master_header+MAX_FIELDS_NAME_LENGTH, 114559599516SKenneth E. Jansen mpi_tag, 114659599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH); 114759599516SKenneth E. Jansen 114859599516SKenneth E. Jansen bzero((void*)mpi_tag,MAX_FIELDS_NAME_LENGTH); 114959599516SKenneth E. Jansen sprintf(mpi_tag, "\nnPPF : %d\n", PhastaIOActiveFiles[i]->nPPF); 115059599516SKenneth E. Jansen memcpy( PhastaIOActiveFiles[i]->master_header+ 115159599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nFields * 115259599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH + 115359599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH * 2, 115459599516SKenneth E. Jansen mpi_tag, 115559599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH); 115659599516SKenneth E. Jansen 115759599516SKenneth E. Jansen memcpy( PhastaIOActiveFiles[i]->master_header+sizeof("MPI_IO_Tag : ")-1, //-1 sizeof returns the size of the string+1 for "\0" 115859599516SKenneth E. Jansen &magic_number, 115959599516SKenneth E. Jansen sizeof(int)); 116059599516SKenneth E. Jansen 116159599516SKenneth E. Jansen memcpy( PhastaIOActiveFiles[i]->master_header+sizeof("mhsize : ") -1 + MAX_FIELDS_NAME_LENGTH/4*3, 116259599516SKenneth E. Jansen &MasterHeaderSize, 116359599516SKenneth E. Jansen sizeof(int)); 116459599516SKenneth E. Jansen } 116559599516SKenneth E. Jansen 116659599516SKenneth E. Jansen int j = 0; 11672dd307a1SCameron Smith unsigned long **header_table; 11682dd307a1SCameron Smith header_table = ( unsigned long ** )calloc(PhastaIOActiveFiles[i]->nFields, sizeof(unsigned long *)); 116959599516SKenneth E. Jansen 117059599516SKenneth E. Jansen for ( j = 0; j < PhastaIOActiveFiles[i]->nFields; j++ ) { 11712dd307a1SCameron Smith header_table[j]=( unsigned long * ) calloc( PhastaIOActiveFiles[i]->nPPF , sizeof( unsigned long)); 117259599516SKenneth E. Jansen } 117359599516SKenneth E. Jansen 117459599516SKenneth E. Jansen //if( irank == 0 ) printf("gonna mpi_gather, myrank = %d\n", irank); 117559599516SKenneth E. Jansen for ( j = 0; j < PhastaIOActiveFiles[i]->nFields; j++ ) { 117659599516SKenneth E. Jansen MPI_Gather( PhastaIOActiveFiles[i]->my_offset_table[j], 117759599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nppp, 117859599516SKenneth E. Jansen MPI_LONG_LONG_INT, 117959599516SKenneth E. Jansen header_table[j], 118059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nppp, 118159599516SKenneth E. Jansen MPI_LONG_LONG_INT, 118259599516SKenneth E. Jansen 0, 118359599516SKenneth E. Jansen PhastaIOActiveFiles[i]->local_comm ); 118459599516SKenneth E. Jansen } 118559599516SKenneth E. Jansen 118659599516SKenneth E. Jansen if ( PhastaIOActiveFiles[i]->local_myrank == 0 ) { 118759599516SKenneth E. Jansen 118859599516SKenneth E. Jansen //if( irank == 0 ) printf("gonna memcpy for every procs, myrank = %d\n", irank); 118959599516SKenneth E. Jansen for ( j = 0; j < PhastaIOActiveFiles[i]->nFields; j++ ) { 119059599516SKenneth E. Jansen memcpy ( PhastaIOActiveFiles[i]->master_header + 119159599516SKenneth E. Jansen VERSION_INFO_HEADER_SIZE + 11922dd307a1SCameron Smith j * PhastaIOActiveFiles[i]->nPPF * sizeof(unsigned long), 119359599516SKenneth E. Jansen header_table[j], 11942dd307a1SCameron Smith PhastaIOActiveFiles[i]->nPPF * sizeof(unsigned long) ); 119559599516SKenneth E. Jansen } 119659599516SKenneth E. Jansen 119759599516SKenneth E. Jansen //if( irank == 0 ) printf("gonna file_write_at(), myrank = %d\n", irank); 119859599516SKenneth E. Jansen MPI_File_write_at( PhastaIOActiveFiles[i]->file_handle, 119959599516SKenneth E. Jansen 0, 120059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->master_header, 120159599516SKenneth E. Jansen MasterHeaderSize, 120259599516SKenneth E. Jansen MPI_CHAR, 120359599516SKenneth E. Jansen &write_header_status ); 120459599516SKenneth E. Jansen } 120559599516SKenneth E. Jansen 120659599516SKenneth E. Jansen ////free(PhastaIOActiveFiles[i]->master_header); 120759599516SKenneth E. Jansen 120859599516SKenneth E. Jansen for ( j = 0; j < PhastaIOActiveFiles[i]->nFields; j++ ) { 120959599516SKenneth E. Jansen free ( header_table[j] ); 121059599516SKenneth E. Jansen } 121159599516SKenneth E. Jansen free (header_table); 121259599516SKenneth E. Jansen } 121359599516SKenneth E. Jansen 121459599516SKenneth E. Jansen //if( irank == 0 ) printf("gonna file_close(), myrank = %d\n", irank); 121559599516SKenneth E. Jansen MPI_File_close( &( PhastaIOActiveFiles[i]->file_handle ) ); 121659599516SKenneth E. Jansen free ( imode ); 121759599516SKenneth E. Jansen } 121859599516SKenneth E. Jansen 121959599516SKenneth E. Jansen endTimer(&timer_end); 122059599516SKenneth E. Jansen printPerf("closefile_", timer_start, timer_end, 0, 0, ""); 122159599516SKenneth E. Jansen } 122259599516SKenneth E. Jansen 12233872e963SCameron Smith int readHeader( FILE* f, const char phrase[], 12243872e963SCameron Smith int* params, int numParams, const char* iotype) { 12253872e963SCameron Smith isBinary(iotype); 12263872e963SCameron Smith return readHeader(f,phrase,params,numParams); 12273872e963SCameron Smith } 12283872e963SCameron Smith 122959599516SKenneth E. Jansen void readheader( int* fileDescriptor, 123059599516SKenneth E. Jansen const char keyphrase[], 123159599516SKenneth E. Jansen void* valueArray, 123259599516SKenneth E. Jansen int* nItems, 123359599516SKenneth E. Jansen const char datatype[], 123459599516SKenneth E. Jansen const char iotype[] ) 123559599516SKenneth E. Jansen { 123659599516SKenneth E. Jansen double timer_start, timer_end; 1237d3337298SCameron Smith 123859599516SKenneth E. Jansen startTimer(&timer_start); 123959599516SKenneth E. Jansen 124059599516SKenneth E. Jansen int i = *fileDescriptor; 124159599516SKenneth E. Jansen checkFileDescriptor("readheader",&i); 124259599516SKenneth E. Jansen 124359599516SKenneth E. Jansen if ( PhastaIONextActiveIndex == 0 ) { 124459599516SKenneth E. Jansen int filePtr = *fileDescriptor - 1; 124559599516SKenneth E. Jansen FILE* fileObject; 124659599516SKenneth E. Jansen int* valueListInt; 124759599516SKenneth E. Jansen 124859599516SKenneth E. Jansen if ( *fileDescriptor < 1 || *fileDescriptor > (int)fileArray.size() ) { 124959599516SKenneth E. Jansen fprintf(stderr,"No file associated with Descriptor %d\n",*fileDescriptor); 125059599516SKenneth E. Jansen fprintf(stderr,"openfile_ function has to be called before \n") ; 125159599516SKenneth E. Jansen fprintf(stderr,"acessing the file\n ") ; 125259599516SKenneth E. Jansen fprintf(stderr,"fatal error: cannot continue, returning out of call\n"); 125359599516SKenneth E. Jansen endTimer(&timer_end); 125459599516SKenneth E. Jansen printPerf("readheader", timer_start, timer_end, 0, 0, ""); 125559599516SKenneth E. Jansen return; 125659599516SKenneth E. Jansen } 125759599516SKenneth E. Jansen 1258961a4ff6SCameron Smith LastHeaderKey[filePtr] = std::string(keyphrase); 125959599516SKenneth E. Jansen LastHeaderNotFound = false; 126059599516SKenneth E. Jansen 126159599516SKenneth E. Jansen fileObject = fileArray[ filePtr ] ; 126259599516SKenneth E. Jansen Wrong_Endian = byte_order[ filePtr ]; 126359599516SKenneth E. Jansen 126459599516SKenneth E. Jansen isBinary( iotype ); 126559599516SKenneth E. Jansen typeSize( datatype ); //redundant call, just avoid a compiler warning. 126659599516SKenneth E. Jansen 126759599516SKenneth E. Jansen // right now we are making the assumption that we will only write integers 126859599516SKenneth E. Jansen // on the header line. 126959599516SKenneth E. Jansen 127059599516SKenneth E. Jansen valueListInt = static_cast< int* >( valueArray ); 127159599516SKenneth E. Jansen int ierr = readHeader( fileObject , 127259599516SKenneth E. Jansen keyphrase, 127359599516SKenneth E. Jansen valueListInt, 127459599516SKenneth E. Jansen *nItems ) ; 127559599516SKenneth E. Jansen 127659599516SKenneth E. Jansen byte_order[ filePtr ] = Wrong_Endian ; 127759599516SKenneth E. Jansen 127859599516SKenneth E. Jansen if ( ierr ) LastHeaderNotFound = true; 127959599516SKenneth E. Jansen 128059599516SKenneth E. Jansen //return ; // don't return, go to the end to print perf 128159599516SKenneth E. Jansen } 128259599516SKenneth E. Jansen else { 128359599516SKenneth E. Jansen unsigned int skip_size; 128459599516SKenneth E. Jansen int* valueListInt; 128559599516SKenneth E. Jansen valueListInt = static_cast <int*>(valueArray); 1286400e9fc0SCameron Smith char* token = NULL; 128759599516SKenneth E. Jansen bool FOUND = false ; 128859599516SKenneth E. Jansen isBinary( iotype ); 128959599516SKenneth E. Jansen 129059599516SKenneth E. Jansen MPI_Status read_offset_status; 129159599516SKenneth E. Jansen char read_out_tag[MAX_FIELDS_NAME_LENGTH]; 1292400e9fc0SCameron Smith memset(read_out_tag, '\0', MAX_FIELDS_NAME_LENGTH); 129359599516SKenneth E. Jansen char readouttag[MAX_FIELDS_NUMBER][MAX_FIELDS_NAME_LENGTH]; 129459599516SKenneth E. Jansen int j; 129559599516SKenneth E. Jansen 129659599516SKenneth E. Jansen int string_length = strlen( keyphrase ); 129759599516SKenneth E. Jansen char* buffer = (char*) malloc ( string_length+1 ); 129859599516SKenneth E. Jansen 129959599516SKenneth E. Jansen strcpy ( buffer, keyphrase ); 130059599516SKenneth E. Jansen buffer[ string_length ] = '\0'; 130159599516SKenneth E. Jansen 130259599516SKenneth E. Jansen char* st2 = strtok ( buffer, "@" ); 130359599516SKenneth E. Jansen st2 = strtok (NULL, "@"); 130459599516SKenneth E. Jansen PhastaIOActiveFiles[i]->GPid = atoi(st2); 130559599516SKenneth E. Jansen if ( char* p = strpbrk(buffer, "@") ) 130659599516SKenneth E. Jansen *p = '\0'; 130759599516SKenneth E. Jansen 130859599516SKenneth E. Jansen // Check if the user has input the right GPid 130959599516SKenneth E. Jansen if ( ( PhastaIOActiveFiles[i]->GPid <= 131059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->myrank * 131159599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nppp )|| 131259599516SKenneth E. Jansen ( PhastaIOActiveFiles[i]->GPid > 131359599516SKenneth E. Jansen ( PhastaIOActiveFiles[i]->myrank + 1 ) * 131459599516SKenneth E. Jansen PhastaIOActiveFiles[i]->nppp ) ) 131559599516SKenneth E. Jansen { 131659599516SKenneth E. Jansen *fileDescriptor = NOT_A_MPI_FILE; 131759599516SKenneth E. Jansen printf("Error readheader: The file is not in syncIO new format, please check! myrank = %d, GPid = %d, nppp = %d, keyphrase = %s\n", PhastaIOActiveFiles[i]->myrank, PhastaIOActiveFiles[i]->GPid, PhastaIOActiveFiles[i]->nppp, keyphrase); 131859599516SKenneth E. Jansen // It is possible atoi could not generate a clear integer from st2 because of additional garbage character in keyphrase 131959599516SKenneth E. Jansen endTimer(&timer_end); 132059599516SKenneth E. Jansen printPerf("readheader", timer_start, timer_end, 0, 0, ""); 132159599516SKenneth E. Jansen return; 132259599516SKenneth E. Jansen } 132359599516SKenneth E. Jansen 132459599516SKenneth E. Jansen // Find the field we want ... 132559599516SKenneth E. Jansen //for ( j = 0; j<MAX_FIELDS_NUMBER; j++ ) 132659599516SKenneth E. Jansen for ( j = 0; j<PhastaIOActiveFiles[i]->nFields; j++ ) 132759599516SKenneth E. Jansen { 132859599516SKenneth E. Jansen memcpy( readouttag[j], 132959599516SKenneth E. Jansen PhastaIOActiveFiles[i]->master_header + j*MAX_FIELDS_NAME_LENGTH+MAX_FIELDS_NAME_LENGTH*2+1, 133059599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH-1 ); 133159599516SKenneth E. Jansen } 133259599516SKenneth E. Jansen 133359599516SKenneth E. Jansen for ( j = 0; j<PhastaIOActiveFiles[i]->nFields; j++ ) 133459599516SKenneth E. Jansen { 133559599516SKenneth E. Jansen token = strtok ( readouttag[j], ":" ); 133659599516SKenneth E. Jansen 133759599516SKenneth E. Jansen //if ( cscompare( buffer, token ) ) 133859599516SKenneth E. Jansen if ( cscompare( token , buffer ) && cscompare( buffer, token ) ) 133959599516SKenneth E. Jansen // This double comparison is required for the field "number of nodes" and all the other fields that start with "number of nodes" (i.g. number of nodes in the mesh"). 134059599516SKenneth E. Jansen // Would be safer to rename "number of nodes" by "number of nodes in the part" so that the name are completely unique. But much more work to do that (Nspre, phParAdapt, etc). 134159599516SKenneth E. Jansen // Since the field name are unique in SyncIO (as it includes part ID), this should be safe and there should be no issue with the "?" trailing character. 134259599516SKenneth E. Jansen { 134359599516SKenneth E. Jansen PhastaIOActiveFiles[i]->read_field_count = j; 134459599516SKenneth E. Jansen FOUND = true; 134559599516SKenneth E. Jansen //printf("buffer: %s | token: %s | j: %d\n",buffer,token,j); 134659599516SKenneth E. Jansen break; 134759599516SKenneth E. Jansen } 134859599516SKenneth E. Jansen } 134959599516SKenneth E. Jansen free(buffer); 135059599516SKenneth E. Jansen 135159599516SKenneth E. Jansen if (!FOUND) 135259599516SKenneth E. Jansen { 135359599516SKenneth E. Jansen //if(irank==0) printf("Warning readheader: Not found %s \n",keyphrase); //PhastaIOActiveFiles[i]->myrank is certainly initialized here. 135459599516SKenneth E. Jansen if(PhastaIOActiveFiles[i]->myrank == 0) printf("WARNING readheader: Not found %s\n",keyphrase); 135559599516SKenneth E. Jansen endTimer(&timer_end); 135659599516SKenneth E. Jansen printPerf("readheader", timer_start, timer_end, 0, 0, ""); 135759599516SKenneth E. Jansen return; 135859599516SKenneth E. Jansen } 135959599516SKenneth E. Jansen 136059599516SKenneth E. Jansen // Find the part we want ... 136159599516SKenneth E. Jansen PhastaIOActiveFiles[i]->read_part_count = PhastaIOActiveFiles[i]->GPid - 136259599516SKenneth E. Jansen PhastaIOActiveFiles[i]->myrank * PhastaIOActiveFiles[i]->nppp - 1; 136359599516SKenneth E. Jansen 136459599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_offset = 136559599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_read_table[PhastaIOActiveFiles[i]->read_field_count][PhastaIOActiveFiles[i]->read_part_count]; 136659599516SKenneth E. Jansen 136759599516SKenneth E. Jansen // printf("****Rank %d offset is %d\n",PhastaIOActiveFiles[i]->myrank,PhastaIOActiveFiles[i]->my_offset); 136859599516SKenneth E. Jansen 136959599516SKenneth E. Jansen // Read each datablock header here ... 137059599516SKenneth E. Jansen 137159599516SKenneth E. Jansen MPI_File_read_at_all( PhastaIOActiveFiles[i]->file_handle, 137259599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_offset+1, 137359599516SKenneth E. Jansen read_out_tag, 137459599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH-1, 137559599516SKenneth E. Jansen MPI_CHAR, 137659599516SKenneth E. Jansen &read_offset_status ); 137759599516SKenneth E. Jansen token = strtok ( read_out_tag, ":" ); 137859599516SKenneth E. Jansen 137959599516SKenneth E. Jansen // printf("&&&&Rank %d read_out_tag is %s\n",PhastaIOActiveFiles[i]->myrank,read_out_tag); 138059599516SKenneth E. Jansen 138159599516SKenneth E. Jansen if( cscompare( keyphrase , token ) ) //No need to compare also token with keyphrase like above. We should already have the right one. Otherwise there is a problem. 138259599516SKenneth E. Jansen { 138359599516SKenneth E. Jansen FOUND = true ; 138459599516SKenneth E. Jansen token = strtok( NULL, " ,;<>" ); 138559599516SKenneth E. Jansen skip_size = atoi( token ); 138659599516SKenneth E. Jansen for( j=0; j < *nItems && ( token = strtok( NULL," ,;<>") ); j++ ) 138759599516SKenneth E. Jansen valueListInt[j] = atoi( token ); 138859599516SKenneth E. Jansen 138959599516SKenneth E. Jansen if ( j < *nItems ) 139059599516SKenneth E. Jansen { 139159599516SKenneth E. Jansen fprintf( stderr, "Expected # of ints not found for: %s\n", keyphrase ); 139259599516SKenneth E. Jansen } 139359599516SKenneth E. Jansen } 139459599516SKenneth E. Jansen else { 139559599516SKenneth E. Jansen //if(irank==0) 139659599516SKenneth E. Jansen if(PhastaIOActiveFiles[i]->myrank == 0) 139759599516SKenneth E. Jansen // If we enter this if, there is a problem with the name of some fields 139859599516SKenneth E. Jansen { 139959599516SKenneth E. Jansen printf("Error readheader: Unexpected mismatch between keyphrase = %s and token = %s\n",keyphrase,token); 140059599516SKenneth E. Jansen } 140159599516SKenneth E. Jansen } 140259599516SKenneth E. Jansen } 140359599516SKenneth E. Jansen 140459599516SKenneth E. Jansen endTimer(&timer_end); 140559599516SKenneth E. Jansen printPerf("readheader", timer_start, timer_end, 0, 0, ""); 140659599516SKenneth E. Jansen 140759599516SKenneth E. Jansen } 140859599516SKenneth E. Jansen 14093956dcfeSCameron Smith void readDataBlock( 14103956dcfeSCameron Smith FILE* fileObject, 14113956dcfeSCameron Smith void* valueArray, 14123956dcfeSCameron Smith int nItems, 14133956dcfeSCameron Smith const char datatype[], 14143956dcfeSCameron Smith const char iotype[] ) 14153956dcfeSCameron Smith { 14163956dcfeSCameron Smith isBinary(iotype); 14173956dcfeSCameron Smith size_t type_size = typeSize( datatype ); 14183956dcfeSCameron Smith if ( binary_format ) { 14193956dcfeSCameron Smith char junk = '\0'; 14203956dcfeSCameron Smith fread( valueArray, type_size, nItems, fileObject ); 14213956dcfeSCameron Smith fread( &junk, sizeof(char), 1 , fileObject ); 14223956dcfeSCameron Smith if ( Wrong_Endian ) SwapArrayByteOrder( valueArray, type_size, nItems ); 14233956dcfeSCameron Smith } else { 14243956dcfeSCameron Smith char* ts1 = StringStripper( datatype ); 14253956dcfeSCameron Smith if ( cscompare( "integer", ts1 ) ) { 14263956dcfeSCameron Smith for( int n=0; n < nItems ; n++ ) 14273956dcfeSCameron Smith fscanf(fileObject, "%d\n",(int*)((int*)valueArray+n) ); 14283956dcfeSCameron Smith } else if ( cscompare( "double", ts1 ) ) { 14293956dcfeSCameron Smith for( int n=0; n < nItems ; n++ ) 14303956dcfeSCameron Smith fscanf(fileObject, "%lf\n",(double*)((double*)valueArray+n) ); 14313956dcfeSCameron Smith } 14323956dcfeSCameron Smith free (ts1); 14333956dcfeSCameron Smith } 14343956dcfeSCameron Smith } 14353956dcfeSCameron Smith 143659599516SKenneth E. Jansen void readdatablock( int* fileDescriptor, 143759599516SKenneth E. Jansen const char keyphrase[], 143859599516SKenneth E. Jansen void* valueArray, 143959599516SKenneth E. Jansen int* nItems, 144059599516SKenneth E. Jansen const char datatype[], 144159599516SKenneth E. Jansen const char iotype[] ) 144259599516SKenneth E. Jansen { 144359599516SKenneth E. Jansen //if(irank == 0) printf("entering readdatablock()\n"); 14442dd307a1SCameron Smith unsigned long data_size = 0; 144559599516SKenneth E. Jansen double timer_start, timer_end; 144659599516SKenneth E. Jansen startTimer(&timer_start); 144759599516SKenneth E. Jansen 144859599516SKenneth E. Jansen int i = *fileDescriptor; 144959599516SKenneth E. Jansen checkFileDescriptor("readdatablock",&i); 145059599516SKenneth E. Jansen 145159599516SKenneth E. Jansen if ( PhastaIONextActiveIndex == 0 ) { 145259599516SKenneth E. Jansen int filePtr = *fileDescriptor - 1; 145359599516SKenneth E. Jansen FILE* fileObject; 145459599516SKenneth E. Jansen char junk; 145559599516SKenneth E. Jansen 145659599516SKenneth E. Jansen if ( *fileDescriptor < 1 || *fileDescriptor > (int)fileArray.size() ) { 145759599516SKenneth E. Jansen fprintf(stderr,"No file associated with Descriptor %d\n",*fileDescriptor); 145859599516SKenneth E. Jansen fprintf(stderr,"openfile_ function has to be called before\n") ; 145959599516SKenneth E. Jansen fprintf(stderr,"acessing the file\n ") ; 146059599516SKenneth E. Jansen fprintf(stderr,"fatal error: cannot continue, returning out of call\n"); 146159599516SKenneth E. Jansen endTimer(&timer_end); 146259599516SKenneth E. Jansen printPerf("readdatablock", timer_start, timer_end, 0, 0, ""); 146359599516SKenneth E. Jansen return; 146459599516SKenneth E. Jansen } 146559599516SKenneth E. Jansen 146659599516SKenneth E. Jansen // error check.. 146759599516SKenneth E. Jansen // since we require that a consistant header always preceed the data block 146859599516SKenneth E. Jansen // let us check to see that it is actually the case. 146959599516SKenneth E. Jansen 1470961a4ff6SCameron Smith if ( ! cscompare( LastHeaderKey[ filePtr ].c_str(), keyphrase ) ) { 147159599516SKenneth E. Jansen fprintf(stderr, "Header not consistant with data block\n"); 1472961a4ff6SCameron Smith fprintf(stderr, "Header: %s\n", LastHeaderKey[ filePtr ].c_str() ); 147359599516SKenneth E. Jansen fprintf(stderr, "DataBlock: %s\n ", keyphrase ); 147459599516SKenneth E. Jansen fprintf(stderr, "Please recheck read sequence \n"); 147559599516SKenneth E. Jansen if( Strict_Error ) { 147659599516SKenneth E. Jansen fprintf(stderr, "fatal error: cannot continue, returning out of call\n"); 147759599516SKenneth E. Jansen endTimer(&timer_end); 147859599516SKenneth E. Jansen printPerf("readdatablock", timer_start, timer_end, 0, 0, ""); 147959599516SKenneth E. Jansen return; 148059599516SKenneth E. Jansen } 148159599516SKenneth E. Jansen } 148259599516SKenneth E. Jansen 148359599516SKenneth E. Jansen if ( LastHeaderNotFound ) { 148459599516SKenneth E. Jansen endTimer(&timer_end); 148559599516SKenneth E. Jansen printPerf("readdatablock", timer_start, timer_end, 0, 0, ""); 148659599516SKenneth E. Jansen return; 148759599516SKenneth E. Jansen } 148859599516SKenneth E. Jansen fileObject = fileArray[ filePtr ]; 148959599516SKenneth E. Jansen Wrong_Endian = byte_order[ filePtr ]; 1490bae968b9SCameron Smith LastHeaderKey.erase(filePtr); 14913956dcfeSCameron Smith readDataBlock(fileObject,valueArray,*nItems,datatype,iotype); 149259599516SKenneth E. Jansen 149359599516SKenneth E. Jansen //return; 149459599516SKenneth E. Jansen } 149559599516SKenneth E. Jansen else { 149659599516SKenneth E. Jansen // printf("read data block\n"); 149759599516SKenneth E. Jansen MPI_Status read_data_status; 149859599516SKenneth E. Jansen size_t type_size = typeSize( datatype ); 149959599516SKenneth E. Jansen int nUnits = *nItems; 150059599516SKenneth E. Jansen isBinary( iotype ); 150159599516SKenneth E. Jansen 150259599516SKenneth E. Jansen // read datablock then 150359599516SKenneth E. Jansen //MR CHANGE 150459599516SKenneth E. Jansen // if ( cscompare ( datatype, "double")) 150559599516SKenneth E. Jansen char* ts2 = StringStripper( datatype ); 150659599516SKenneth E. Jansen if ( cscompare ( "double" , ts2)) 150759599516SKenneth E. Jansen //MR CHANGE END 150859599516SKenneth E. Jansen { 150959599516SKenneth E. Jansen 151059599516SKenneth E. Jansen MPI_File_read_at_all_begin( PhastaIOActiveFiles[i]->file_handle, 151159599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_offset + DB_HEADER_SIZE, 151259599516SKenneth E. Jansen valueArray, 151359599516SKenneth E. Jansen nUnits, 151459599516SKenneth E. Jansen MPI_DOUBLE ); 151559599516SKenneth E. Jansen MPI_File_read_at_all_end( PhastaIOActiveFiles[i]->file_handle, 151659599516SKenneth E. Jansen valueArray, 151759599516SKenneth E. Jansen &read_data_status ); 151859599516SKenneth E. Jansen data_size=8*nUnits; 151959599516SKenneth E. Jansen 152059599516SKenneth E. Jansen } 152159599516SKenneth E. Jansen //MR CHANGE 152259599516SKenneth E. Jansen // else if ( cscompare ( datatype, "integer")) 152359599516SKenneth E. Jansen else if ( cscompare ( "integer" , ts2)) 152459599516SKenneth E. Jansen //MR CHANGE END 152559599516SKenneth E. Jansen { 152659599516SKenneth E. Jansen MPI_File_read_at_all_begin(PhastaIOActiveFiles[i]->file_handle, 152759599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_offset + DB_HEADER_SIZE, 152859599516SKenneth E. Jansen valueArray, 152959599516SKenneth E. Jansen nUnits, 153059599516SKenneth E. Jansen MPI_INT ); 153159599516SKenneth E. Jansen MPI_File_read_at_all_end( PhastaIOActiveFiles[i]->file_handle, 153259599516SKenneth E. Jansen valueArray, 153359599516SKenneth E. Jansen &read_data_status ); 153459599516SKenneth E. Jansen data_size=4*nUnits; 153559599516SKenneth E. Jansen } 153659599516SKenneth E. Jansen else 153759599516SKenneth E. Jansen { 153859599516SKenneth E. Jansen *fileDescriptor = DATA_TYPE_ILLEGAL; 153959599516SKenneth E. Jansen printf("readdatablock - DATA_TYPE_ILLEGAL - %s\n",datatype); 154059599516SKenneth E. Jansen endTimer(&timer_end); 154159599516SKenneth E. Jansen printPerf("readdatablock", timer_start, timer_end, 0, 0, ""); 154259599516SKenneth E. Jansen return; 154359599516SKenneth E. Jansen } 154459599516SKenneth E. Jansen free(ts2); 154559599516SKenneth E. Jansen 154659599516SKenneth E. Jansen 154759599516SKenneth E. Jansen // printf("%d Read finishe\n",PhastaIOActiveFiles[i]->myrank); 154859599516SKenneth E. Jansen 154959599516SKenneth E. Jansen // Swap data byte order if endianess is different ... 155059599516SKenneth E. Jansen if ( PhastaIOActiveFiles[i]->Wrong_Endian ) 155159599516SKenneth E. Jansen { 155259599516SKenneth E. Jansen SwapArrayByteOrder( valueArray, type_size, nUnits ); 155359599516SKenneth E. Jansen } 155459599516SKenneth E. Jansen } 155559599516SKenneth E. Jansen 155659599516SKenneth E. Jansen endTimer(&timer_end); 155759599516SKenneth E. Jansen char extra_msg[1024]; 155859599516SKenneth E. Jansen memset(extra_msg, '\0', 1024); 155959599516SKenneth E. Jansen char* key = StringStripper(keyphrase); 156059599516SKenneth E. Jansen sprintf(extra_msg, " field is %s ", key); 156159599516SKenneth E. Jansen printPerf("readdatablock", timer_start, timer_end, data_size, 1, extra_msg); 156259599516SKenneth E. Jansen free(key); 156359599516SKenneth E. Jansen 156459599516SKenneth E. Jansen } 156559599516SKenneth E. Jansen 1566ea868eb1SCameron Smith void writeHeader(FILE* f, 1567ea868eb1SCameron Smith const char keyphrase[], 1568ea868eb1SCameron Smith const void* valueArray, 1569ea868eb1SCameron Smith const int nItems, 1570ea868eb1SCameron Smith const int ndataItems, 1571ea868eb1SCameron Smith const char datatype[], 1572ea868eb1SCameron Smith const char iotype[]) 1573ea868eb1SCameron Smith { 1574ea868eb1SCameron Smith isBinary( iotype ); 1575ea868eb1SCameron Smith 1576ea868eb1SCameron Smith const int _newline = 1577ea868eb1SCameron Smith ( ndataItems > 0 ) ? sizeof( char ) : 0; 1578ea868eb1SCameron Smith int size_of_nextblock = 1579ea868eb1SCameron Smith ( binary_format ) ? typeSize(datatype) * ndataItems + _newline : ndataItems; 1580ea868eb1SCameron Smith 1581ea868eb1SCameron Smith fprintf( f, "%s : < %d > ", keyphrase, size_of_nextblock ); 1582ea868eb1SCameron Smith for( int i = 0; i < nItems; i++ ) 1583ea868eb1SCameron Smith fprintf( f, "%d ", *((int*)((int*)valueArray+i))); 1584ea868eb1SCameron Smith fprintf( f, "\n"); 1585ea868eb1SCameron Smith } 1586ea868eb1SCameron Smith 158759599516SKenneth E. Jansen void writeheader( const int* fileDescriptor, 158859599516SKenneth E. Jansen const char keyphrase[], 158959599516SKenneth E. Jansen const void* valueArray, 159059599516SKenneth E. Jansen const int* nItems, 159159599516SKenneth E. Jansen const int* ndataItems, 159259599516SKenneth E. Jansen const char datatype[], 159359599516SKenneth E. Jansen const char iotype[]) 159459599516SKenneth E. Jansen { 159559599516SKenneth E. Jansen 159659599516SKenneth E. Jansen //if(irank == 0) printf("entering writeheader()\n"); 159759599516SKenneth E. Jansen 159859599516SKenneth E. Jansen double timer_start, timer_end; 159959599516SKenneth E. Jansen startTimer(&timer_start); 160059599516SKenneth E. Jansen 160159599516SKenneth E. Jansen int i = *fileDescriptor; 160259599516SKenneth E. Jansen checkFileDescriptor("writeheader",&i); 160359599516SKenneth E. Jansen 160459599516SKenneth E. Jansen if ( PhastaIONextActiveIndex == 0 ) { 160559599516SKenneth E. Jansen int filePtr = *fileDescriptor - 1; 160659599516SKenneth E. Jansen if ( *fileDescriptor < 1 || *fileDescriptor > (int)fileArray.size() ) { 160759599516SKenneth E. Jansen fprintf(stderr,"No file associated with Descriptor %d\n",*fileDescriptor); 160859599516SKenneth E. Jansen fprintf(stderr,"openfile_ function has to be called before \n") ; 160959599516SKenneth E. Jansen fprintf(stderr,"acessing the file\n ") ; 161059599516SKenneth E. Jansen fprintf(stderr,"fatal error: cannot continue, returning out of call\n"); 161159599516SKenneth E. Jansen endTimer(&timer_end); 161259599516SKenneth E. Jansen printPerf("writeheader", timer_start, timer_end, 0, 0, ""); 161359599516SKenneth E. Jansen return; 161459599516SKenneth E. Jansen } 161559599516SKenneth E. Jansen 1616961a4ff6SCameron Smith LastHeaderKey[filePtr] = std::string(keyphrase); 161759599516SKenneth E. Jansen DataSize = *ndataItems; 1618ea868eb1SCameron Smith FILE* fileObject = fileArray[ filePtr ] ; 1619ea868eb1SCameron Smith header_type[ filePtr ] = typeSize( datatype ); 1620ea868eb1SCameron Smith writeHeader(fileObject,keyphrase,valueArray,*nItems, 1621ea868eb1SCameron Smith *ndataItems,datatype,iotype); 162259599516SKenneth E. Jansen } 162359599516SKenneth E. Jansen else { // else it's parallel I/O 162459599516SKenneth E. Jansen DataSize = *ndataItems; 162559599516SKenneth E. Jansen size_t type_size = typeSize( datatype ); 162659599516SKenneth E. Jansen isBinary( iotype ); 162759599516SKenneth E. Jansen char mpi_tag[MAX_FIELDS_NAME_LENGTH]; 162859599516SKenneth E. Jansen 162959599516SKenneth E. Jansen int string_length = strlen( keyphrase ); 163059599516SKenneth E. Jansen char* buffer = (char*) malloc ( string_length+1 ); 163159599516SKenneth E. Jansen 163259599516SKenneth E. Jansen strcpy ( buffer, keyphrase); 163359599516SKenneth E. Jansen buffer[ string_length ] = '\0'; 163459599516SKenneth E. Jansen 163559599516SKenneth E. Jansen char* st2 = strtok ( buffer, "@" ); 163659599516SKenneth E. Jansen st2 = strtok (NULL, "@"); 163759599516SKenneth E. Jansen PhastaIOActiveFiles[i]->GPid = atoi(st2); 163859599516SKenneth E. Jansen 163959599516SKenneth E. Jansen if ( char* p = strpbrk(buffer, "@") ) 164059599516SKenneth E. Jansen *p = '\0'; 164159599516SKenneth E. Jansen 164259599516SKenneth E. Jansen bzero((void*)mpi_tag,MAX_FIELDS_NAME_LENGTH); 164359599516SKenneth E. Jansen sprintf(mpi_tag, "\n%s : %d\n", buffer, PhastaIOActiveFiles[i]->field_count); 16442dd307a1SCameron Smith unsigned long offset_value; 164559599516SKenneth E. Jansen 164659599516SKenneth E. Jansen int temp = *ndataItems; 16472dd307a1SCameron Smith unsigned long number_of_items = (unsigned long)temp; 164859599516SKenneth E. Jansen MPI_Barrier(PhastaIOActiveFiles[i]->local_comm); 164959599516SKenneth E. Jansen 165059599516SKenneth E. Jansen MPI_Scan( &number_of_items, 165159599516SKenneth E. Jansen &offset_value, 165259599516SKenneth E. Jansen 1, 165359599516SKenneth E. Jansen MPI_LONG_LONG_INT, 165459599516SKenneth E. Jansen MPI_SUM, 165559599516SKenneth E. Jansen PhastaIOActiveFiles[i]->local_comm ); 165659599516SKenneth E. Jansen 165759599516SKenneth E. Jansen offset_value = (offset_value - number_of_items) * type_size; 165859599516SKenneth E. Jansen 165959599516SKenneth E. Jansen offset_value += PhastaIOActiveFiles[i]->local_myrank * 166059599516SKenneth E. Jansen DB_HEADER_SIZE + 166159599516SKenneth E. Jansen PhastaIOActiveFiles[i]->next_start_address; 166259599516SKenneth E. Jansen // This offset is the starting address of each datablock header... 166359599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_offset = offset_value; 166459599516SKenneth E. Jansen 166559599516SKenneth E. Jansen // Write in my offset table ... 166659599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_offset_table[PhastaIOActiveFiles[i]->field_count][PhastaIOActiveFiles[i]->part_count] = 166759599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_offset; 166859599516SKenneth E. Jansen 166959599516SKenneth E. Jansen // Update the next-start-address ... 167059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->next_start_address = offset_value + 167159599516SKenneth E. Jansen number_of_items * type_size + 167259599516SKenneth E. Jansen DB_HEADER_SIZE; 167359599516SKenneth E. Jansen MPI_Bcast( &(PhastaIOActiveFiles[i]->next_start_address), 167459599516SKenneth E. Jansen 1, 167559599516SKenneth E. Jansen MPI_LONG_LONG_INT, 167659599516SKenneth E. Jansen PhastaIOActiveFiles[i]->local_numprocs-1, 167759599516SKenneth E. Jansen PhastaIOActiveFiles[i]->local_comm ); 167859599516SKenneth E. Jansen 167959599516SKenneth E. Jansen // Prepare datablock header ... 168059599516SKenneth E. Jansen int _newline = (*ndataItems>0)?sizeof(char):0; 168159599516SKenneth E. Jansen unsigned int size_of_nextblock = type_size * (*ndataItems) + _newline; 168259599516SKenneth E. Jansen 168359599516SKenneth E. Jansen //char datablock_header[255]; 168459599516SKenneth E. Jansen //bzero((void*)datablock_header,255); 168559599516SKenneth E. Jansen char datablock_header[DB_HEADER_SIZE]; 168659599516SKenneth E. Jansen bzero((void*)datablock_header,DB_HEADER_SIZE); 168759599516SKenneth E. Jansen 168859599516SKenneth E. Jansen PhastaIOActiveFiles[i]->GPid = PhastaIOActiveFiles[i]->nppp*PhastaIOActiveFiles[i]->myrank+PhastaIOActiveFiles[i]->part_count; 168959599516SKenneth E. Jansen sprintf( datablock_header, 169059599516SKenneth E. Jansen "\n%s : < %u >", 169159599516SKenneth E. Jansen keyphrase, 169259599516SKenneth E. Jansen size_of_nextblock ); 169359599516SKenneth E. Jansen 169459599516SKenneth E. Jansen for ( int j = 0; j < *nItems; j++ ) 169559599516SKenneth E. Jansen { 169659599516SKenneth E. Jansen sprintf( datablock_header, 169759599516SKenneth E. Jansen "%s %d ", 169859599516SKenneth E. Jansen datablock_header, 169959599516SKenneth E. Jansen *((int*)((int*)valueArray+j))); 170059599516SKenneth E. Jansen } 170159599516SKenneth E. Jansen sprintf( datablock_header, 170259599516SKenneth E. Jansen "%s\n ", 170359599516SKenneth E. Jansen datablock_header ); 170459599516SKenneth E. Jansen 170559599516SKenneth E. Jansen // Write datablock header ... 170659599516SKenneth E. Jansen //MR CHANGE 170759599516SKenneth E. Jansen // if ( cscompare(datatype,"double") ) 170859599516SKenneth E. Jansen char* ts1 = StringStripper( datatype ); 170959599516SKenneth E. Jansen if ( cscompare("double",ts1) ) 171059599516SKenneth E. Jansen //MR CHANGE END 171159599516SKenneth E. Jansen { 171259599516SKenneth E. Jansen free ( PhastaIOActiveFiles[i]->double_chunk ); 171359599516SKenneth E. Jansen PhastaIOActiveFiles[i]->double_chunk = ( double * )malloc( (sizeof( double )*number_of_items+ DB_HEADER_SIZE)); 171459599516SKenneth E. Jansen 171559599516SKenneth E. Jansen double * aa = ( double * )datablock_header; 171659599516SKenneth E. Jansen memcpy(PhastaIOActiveFiles[i]->double_chunk, aa, DB_HEADER_SIZE); 171759599516SKenneth E. Jansen } 171859599516SKenneth E. Jansen //MR CHANGE 171959599516SKenneth E. Jansen // if ( cscompare(datatype,"integer") ) 172059599516SKenneth E. Jansen else if ( cscompare("integer",ts1) ) 172159599516SKenneth E. Jansen //MR CHANGE END 172259599516SKenneth E. Jansen { 172359599516SKenneth E. Jansen free ( PhastaIOActiveFiles[i]->int_chunk ); 172459599516SKenneth E. Jansen PhastaIOActiveFiles[i]->int_chunk = ( int * )malloc( (sizeof( int )*number_of_items+ DB_HEADER_SIZE)); 172559599516SKenneth E. Jansen 172659599516SKenneth E. Jansen int * aa = ( int * )datablock_header; 172759599516SKenneth E. Jansen memcpy(PhastaIOActiveFiles[i]->int_chunk, aa, DB_HEADER_SIZE); 172859599516SKenneth E. Jansen } 172959599516SKenneth E. Jansen else { 173059599516SKenneth E. Jansen // *fileDescriptor = DATA_TYPE_ILLEGAL; 173159599516SKenneth E. Jansen printf("writeheader - DATA_TYPE_ILLEGAL - %s\n",datatype); 173259599516SKenneth E. Jansen endTimer(&timer_end); 173359599516SKenneth E. Jansen printPerf("writeheader", timer_start, timer_end, 0, 0, ""); 173459599516SKenneth E. Jansen return; 173559599516SKenneth E. Jansen } 173659599516SKenneth E. Jansen free(ts1); 173759599516SKenneth E. Jansen 173859599516SKenneth E. Jansen PhastaIOActiveFiles[i]->part_count++; 173959599516SKenneth E. Jansen if ( PhastaIOActiveFiles[i]->part_count == PhastaIOActiveFiles[i]->nppp ) { 174059599516SKenneth E. Jansen //A new field will be written 174159599516SKenneth E. Jansen if ( PhastaIOActiveFiles[i]->local_myrank == 0 ) { 174259599516SKenneth E. Jansen memcpy( PhastaIOActiveFiles[i]->master_header + 174359599516SKenneth E. Jansen PhastaIOActiveFiles[i]->field_count * 174459599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH + 174559599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH * 2, 174659599516SKenneth E. Jansen mpi_tag, 174759599516SKenneth E. Jansen MAX_FIELDS_NAME_LENGTH-1); 174859599516SKenneth E. Jansen } 174959599516SKenneth E. Jansen PhastaIOActiveFiles[i]->field_count++; 175059599516SKenneth E. Jansen PhastaIOActiveFiles[i]->part_count=0; 175159599516SKenneth E. Jansen } 175259599516SKenneth E. Jansen free(buffer); 175359599516SKenneth E. Jansen } 175459599516SKenneth E. Jansen 175559599516SKenneth E. Jansen endTimer(&timer_end); 175659599516SKenneth E. Jansen printPerf("writeheader", timer_start, timer_end, 0, 0, ""); 175759599516SKenneth E. Jansen } 175859599516SKenneth E. Jansen 1759ea868eb1SCameron Smith void writeDataBlock( FILE* f, 1760ea868eb1SCameron Smith const void* valueArray, 1761ea868eb1SCameron Smith const int nItems, 1762ea868eb1SCameron Smith const char datatype[], 1763ea868eb1SCameron Smith const char iotype[] ) 1764ea868eb1SCameron Smith { 1765ea868eb1SCameron Smith isBinary( iotype ); 1766ea868eb1SCameron Smith size_t type_size = typeSize( datatype ); 1767ea868eb1SCameron Smith if ( binary_format ) { 1768ea868eb1SCameron Smith fwrite( valueArray, type_size, nItems, f ); 1769ea868eb1SCameron Smith fprintf( f,"\n"); 1770ea868eb1SCameron Smith } else { 1771ea868eb1SCameron Smith char* ts1 = StringStripper( datatype ); 1772ea868eb1SCameron Smith if ( cscompare( "integer", ts1 ) ) { 1773ea868eb1SCameron Smith for( int n=0; n < nItems ; n++ ) 1774ea868eb1SCameron Smith fprintf(f,"%d\n",*((int*)((int*)valueArray+n))); 1775ea868eb1SCameron Smith } else if ( cscompare( "double", ts1 ) ) { 1776ea868eb1SCameron Smith for( int n=0; n < nItems ; n++ ) 1777ea868eb1SCameron Smith fprintf(f,"%lf\n",*((double*)((double*)valueArray+n))); 1778ea868eb1SCameron Smith } 1779ea868eb1SCameron Smith free (ts1); 1780ea868eb1SCameron Smith } 1781ea868eb1SCameron Smith } 1782ea868eb1SCameron Smith 178359599516SKenneth E. Jansen void writedatablock( const int* fileDescriptor, 178459599516SKenneth E. Jansen const char keyphrase[], 178559599516SKenneth E. Jansen const void* valueArray, 178659599516SKenneth E. Jansen const int* nItems, 178759599516SKenneth E. Jansen const char datatype[], 178859599516SKenneth E. Jansen const char iotype[] ) 178959599516SKenneth E. Jansen { 179059599516SKenneth E. Jansen //if(irank == 0) printf("entering writedatablock()\n"); 179159599516SKenneth E. Jansen 17922dd307a1SCameron Smith unsigned long data_size = 0; 179359599516SKenneth E. Jansen double timer_start, timer_end; 179459599516SKenneth E. Jansen startTimer(&timer_start); 179559599516SKenneth E. Jansen 179659599516SKenneth E. Jansen int i = *fileDescriptor; 179759599516SKenneth E. Jansen checkFileDescriptor("writedatablock",&i); 179859599516SKenneth E. Jansen 179959599516SKenneth E. Jansen if ( PhastaIONextActiveIndex == 0 ) { 180059599516SKenneth E. Jansen int filePtr = *fileDescriptor - 1; 180159599516SKenneth E. Jansen 180259599516SKenneth E. Jansen if ( *fileDescriptor < 1 || *fileDescriptor > (int)fileArray.size() ) { 180359599516SKenneth E. Jansen fprintf(stderr,"No file associated with Descriptor %d\n",*fileDescriptor); 180459599516SKenneth E. Jansen fprintf(stderr,"openfile_ function has to be called before \n") ; 180559599516SKenneth E. Jansen fprintf(stderr,"acessing the file\n ") ; 180659599516SKenneth E. Jansen fprintf(stderr,"fatal error: cannot continue, returning out of call\n"); 180759599516SKenneth E. Jansen endTimer(&timer_end); 180859599516SKenneth E. Jansen printPerf("writedatablock", timer_start, timer_end, 0, 0, ""); 180959599516SKenneth E. Jansen return; 181059599516SKenneth E. Jansen } 181159599516SKenneth E. Jansen // since we require that a consistant header always preceed the data block 181259599516SKenneth E. Jansen // let us check to see that it is actually the case. 181359599516SKenneth E. Jansen 1814961a4ff6SCameron Smith if ( ! cscompare( LastHeaderKey[ filePtr ].c_str(), keyphrase ) ) { 181559599516SKenneth E. Jansen fprintf(stderr, "Header not consistant with data block\n"); 1816961a4ff6SCameron Smith fprintf(stderr, "Header: %s\n", LastHeaderKey[ filePtr ].c_str() ); 181759599516SKenneth E. Jansen fprintf(stderr, "DataBlock: %s\n ", keyphrase ); 181859599516SKenneth E. Jansen fprintf(stderr, "Please recheck write sequence \n"); 181959599516SKenneth E. Jansen if( Strict_Error ) { 182059599516SKenneth E. Jansen fprintf(stderr, "fatal error: cannot continue, returning out of call\n"); 182159599516SKenneth E. Jansen endTimer(&timer_end); 182259599516SKenneth E. Jansen printPerf("writedatablock", timer_start, timer_end, 0, 0, ""); 182359599516SKenneth E. Jansen return; 182459599516SKenneth E. Jansen } 182559599516SKenneth E. Jansen } 182659599516SKenneth E. Jansen 182759599516SKenneth E. Jansen FILE* fileObject = fileArray[ filePtr ] ; 182859599516SKenneth E. Jansen size_t type_size=typeSize( datatype ); 182959599516SKenneth E. Jansen isBinary( iotype ); 183059599516SKenneth E. Jansen 1831bae968b9SCameron Smith LastHeaderKey.erase(filePtr); 1832bae968b9SCameron Smith 183359599516SKenneth E. Jansen if ( header_type[filePtr] != (int)type_size ) { 183459599516SKenneth E. Jansen fprintf(stderr,"header and datablock differ on typeof data in the block for\n"); 183559599516SKenneth E. Jansen fprintf(stderr,"keyphrase : %s\n", keyphrase); 183659599516SKenneth E. Jansen if( Strict_Error ) { 183759599516SKenneth E. Jansen fprintf(stderr,"fatal error: cannot continue, returning out of call\n" ); 183859599516SKenneth E. Jansen endTimer(&timer_end); 183959599516SKenneth E. Jansen printPerf("writedatablock", timer_start, timer_end, 0, 0, ""); 184059599516SKenneth E. Jansen return; 184159599516SKenneth E. Jansen } 184259599516SKenneth E. Jansen } 184359599516SKenneth E. Jansen 184459599516SKenneth E. Jansen int nUnits = *nItems; 184559599516SKenneth E. Jansen 184659599516SKenneth E. Jansen if ( nUnits != DataSize ) { 184759599516SKenneth E. Jansen fprintf(stderr,"header and datablock differ on number of data items for\n"); 184859599516SKenneth E. Jansen fprintf(stderr,"keyphrase : %s\n", keyphrase); 184959599516SKenneth E. Jansen if( Strict_Error ) { 185059599516SKenneth E. Jansen fprintf(stderr,"fatal error: cannot continue, returning out of call\n" ); 185159599516SKenneth E. Jansen endTimer(&timer_end); 185259599516SKenneth E. Jansen printPerf("writedatablock", timer_start, timer_end, 0, 0, ""); 185359599516SKenneth E. Jansen return; 185459599516SKenneth E. Jansen } 185559599516SKenneth E. Jansen } 1856ea868eb1SCameron Smith writeDataBlock(fileObject,valueArray,*nItems,datatype,iotype); 185759599516SKenneth E. Jansen } 185859599516SKenneth E. Jansen else { // syncIO case 185959599516SKenneth E. Jansen MPI_Status write_data_status; 186059599516SKenneth E. Jansen isBinary( iotype ); 186159599516SKenneth E. Jansen int nUnits = *nItems; 186259599516SKenneth E. Jansen 186359599516SKenneth E. Jansen //MR CHANGE 186459599516SKenneth E. Jansen // if ( cscompare(datatype,"double") ) 186559599516SKenneth E. Jansen char* ts1 = StringStripper( datatype ); 186659599516SKenneth E. Jansen if ( cscompare("double",ts1) ) 186759599516SKenneth E. Jansen //MR CHANGE END 186859599516SKenneth E. Jansen { 186959599516SKenneth E. Jansen memcpy((PhastaIOActiveFiles[i]->double_chunk+DB_HEADER_SIZE/sizeof(double)), valueArray, nUnits*sizeof(double)); 187059599516SKenneth E. Jansen MPI_File_write_at_all_begin( PhastaIOActiveFiles[i]->file_handle, 187159599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_offset, 187259599516SKenneth E. Jansen PhastaIOActiveFiles[i]->double_chunk, 187359599516SKenneth E. Jansen //BLOCK_SIZE/sizeof(double), 187459599516SKenneth E. Jansen nUnits+DB_HEADER_SIZE/sizeof(double), 187559599516SKenneth E. Jansen MPI_DOUBLE ); 187659599516SKenneth E. Jansen MPI_File_write_at_all_end( PhastaIOActiveFiles[i]->file_handle, 187759599516SKenneth E. Jansen PhastaIOActiveFiles[i]->double_chunk, 187859599516SKenneth E. Jansen &write_data_status ); 187959599516SKenneth E. Jansen data_size=8*nUnits; 188059599516SKenneth E. Jansen } 188159599516SKenneth E. Jansen //MR CHANGE 188259599516SKenneth E. Jansen // else if ( cscompare ( datatype, "integer")) 188359599516SKenneth E. Jansen else if ( cscompare("integer",ts1) ) 188459599516SKenneth E. Jansen //MR CHANGE END 188559599516SKenneth E. Jansen { 188659599516SKenneth E. Jansen memcpy((PhastaIOActiveFiles[i]->int_chunk+DB_HEADER_SIZE/sizeof(int)), valueArray, nUnits*sizeof(int)); 188759599516SKenneth E. Jansen MPI_File_write_at_all_begin( PhastaIOActiveFiles[i]->file_handle, 188859599516SKenneth E. Jansen PhastaIOActiveFiles[i]->my_offset, 188959599516SKenneth E. Jansen PhastaIOActiveFiles[i]->int_chunk, 189059599516SKenneth E. Jansen nUnits+DB_HEADER_SIZE/sizeof(int), 189159599516SKenneth E. Jansen MPI_INT ); 189259599516SKenneth E. Jansen MPI_File_write_at_all_end( PhastaIOActiveFiles[i]->file_handle, 189359599516SKenneth E. Jansen PhastaIOActiveFiles[i]->int_chunk, 189459599516SKenneth E. Jansen &write_data_status ); 189559599516SKenneth E. Jansen data_size=4*nUnits; 189659599516SKenneth E. Jansen } 189759599516SKenneth E. Jansen else { 189859599516SKenneth E. Jansen printf("Error: writedatablock - DATA_TYPE_ILLEGAL - %s\n",datatype); 189959599516SKenneth E. Jansen endTimer(&timer_end); 190059599516SKenneth E. Jansen printPerf("writedatablock", timer_start, timer_end, 0, 0, ""); 190159599516SKenneth E. Jansen return; 190259599516SKenneth E. Jansen } 190359599516SKenneth E. Jansen free(ts1); 190459599516SKenneth E. Jansen } 190559599516SKenneth E. Jansen 190659599516SKenneth E. Jansen endTimer(&timer_end); 190759599516SKenneth E. Jansen char extra_msg[1024]; 190859599516SKenneth E. Jansen memset(extra_msg, '\0', 1024); 190959599516SKenneth E. Jansen char* key = StringStripper(keyphrase); 191059599516SKenneth E. Jansen sprintf(extra_msg, " field is %s ", key); 191159599516SKenneth E. Jansen printPerf("writedatablock", timer_start, timer_end, data_size, 1, extra_msg); 191259599516SKenneth E. Jansen free(key); 191359599516SKenneth E. Jansen 191459599516SKenneth E. Jansen } 191559599516SKenneth E. Jansen 191659599516SKenneth E. Jansen void 191759599516SKenneth E. Jansen SwapArrayByteOrder( void* array, 191859599516SKenneth E. Jansen int nbytes, 191959599516SKenneth E. Jansen int nItems ) 192059599516SKenneth E. Jansen { 192159599516SKenneth E. Jansen /* This swaps the byte order for the array of nItems each 192259599516SKenneth E. Jansen of size nbytes , This will be called only locally */ 192359599516SKenneth E. Jansen int i,j; 192459599516SKenneth E. Jansen unsigned char* ucDst = (unsigned char*)array; 192559599516SKenneth E. Jansen 192659599516SKenneth E. Jansen for(i=0; i < nItems; i++) { 192759599516SKenneth E. Jansen for(j=0; j < (nbytes/2); j++) 192859599516SKenneth E. Jansen std::swap( ucDst[j] , ucDst[(nbytes - 1) - j] ); 192959599516SKenneth E. Jansen ucDst += nbytes; 193059599516SKenneth E. Jansen } 193159599516SKenneth E. Jansen } 193259599516SKenneth E. Jansen 193359599516SKenneth E. Jansen void 193459599516SKenneth E. Jansen writestring( int* fileDescriptor, 193559599516SKenneth E. Jansen const char inString[] ) 193659599516SKenneth E. Jansen { 193759599516SKenneth E. Jansen 193859599516SKenneth E. Jansen int filePtr = *fileDescriptor - 1; 193959599516SKenneth E. Jansen FILE* fileObject = fileArray[filePtr] ; 194059599516SKenneth E. Jansen fprintf(fileObject,"%s",inString ); 194159599516SKenneth E. Jansen return; 194259599516SKenneth E. Jansen } 194359599516SKenneth E. Jansen 194459599516SKenneth E. Jansen void 194559599516SKenneth E. Jansen Gather_Headers( int* fileDescriptor, 194659599516SKenneth E. Jansen vector< string >& headers ) 194759599516SKenneth E. Jansen { 194859599516SKenneth E. Jansen 194959599516SKenneth E. Jansen FILE* fileObject; 195059599516SKenneth E. Jansen char Line[1024]; 195159599516SKenneth E. Jansen 195259599516SKenneth E. Jansen fileObject = fileArray[ (*fileDescriptor)-1 ]; 195359599516SKenneth E. Jansen 195459599516SKenneth E. Jansen while( !feof(fileObject) ) { 195559599516SKenneth E. Jansen fgets( Line, 1024, fileObject); 195659599516SKenneth E. Jansen if ( Line[0] == '#' ) { 195759599516SKenneth E. Jansen headers.push_back( Line ); 195859599516SKenneth E. Jansen } else { 195959599516SKenneth E. Jansen break; 196059599516SKenneth E. Jansen } 196159599516SKenneth E. Jansen } 196259599516SKenneth E. Jansen rewind( fileObject ); 196359599516SKenneth E. Jansen clearerr( fileObject ); 196459599516SKenneth E. Jansen } 196559599516SKenneth E. Jansen void 196659599516SKenneth E. Jansen isWrong( void ) { (Wrong_Endian) ? fprintf(stdout,"YES\n"): fprintf(stdout,"NO\n") ; } 196759599516SKenneth E. Jansen 196859599516SKenneth E. Jansen void 196959599516SKenneth E. Jansen togglestrictmode( void ) { Strict_Error = !Strict_Error; } 197059599516SKenneth E. Jansen 197159599516SKenneth E. Jansen int 197259599516SKenneth E. Jansen isLittleEndian( void ) 197359599516SKenneth E. Jansen { 197459599516SKenneth E. Jansen // this function returns a 1 if the current running architecture is 197559599516SKenneth E. Jansen // LittleEndian Byte Ordered, else it returns a zero 197659599516SKenneth E. Jansen 197759599516SKenneth E. Jansen union { 197859599516SKenneth E. Jansen long a; 197959599516SKenneth E. Jansen char c[sizeof( long )]; 198059599516SKenneth E. Jansen } endianUnion; 198159599516SKenneth E. Jansen 198259599516SKenneth E. Jansen endianUnion.a = 1 ; 198359599516SKenneth E. Jansen 198459599516SKenneth E. Jansen if ( endianUnion.c[sizeof(long)-1] != 1 ) return 1 ; 198559599516SKenneth E. Jansen else return 0; 198659599516SKenneth E. Jansen } 198759599516SKenneth E. Jansen 198859599516SKenneth E. Jansen namespace PHASTA { 198959599516SKenneth E. Jansen const char* const PhastaIO_traits<int>::type_string = "integer"; 199059599516SKenneth E. Jansen const char* const PhastaIO_traits<double>::type_string = "double"; 199159599516SKenneth E. Jansen } 1992