diff options
-rw-r--r-- | tools/h5diff/ph5diff_main.c | 47 | ||||
-rw-r--r-- | tools/lib/h5diff.c | 122 | ||||
-rw-r--r-- | tools/lib/h5diff_util.c | 38 | ||||
-rw-r--r-- | tools/lib/ph5diff.h | 11 |
4 files changed, 161 insertions, 57 deletions
diff --git a/tools/h5diff/ph5diff_main.c b/tools/h5diff/ph5diff_main.c index cd252b9..3d34af8 100644 --- a/tools/h5diff/ph5diff_main.c +++ b/tools/h5diff/ph5diff_main.c @@ -98,7 +98,7 @@ int main(int argc, const char *argv[]) MPI_Barrier(MPI_COMM_WORLD); print_results(nfound, &options); - print_manager_output(); + print_manager_output(); MPI_Finalize(); @@ -131,8 +131,10 @@ ph5diff_worker(int nID) struct diff_args args; hid_t file1_id, file2_id; char filenames[2][1024]; + char out_data[PRINT_DATA_MAX_SIZE] = {0}; hsize_t nfound=0; MPI_Status Status; + int i; MPI_Comm_rank(MPI_COMM_WORLD, &nID); outBuffOffset = 0; @@ -140,8 +142,6 @@ ph5diff_worker(int nID) MPI_Recv(filenames, 1024*2, MPI_CHAR, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &Status); if(Status.MPI_TAG == MPI_TAG_PARALLEL) { - /*printf("We're in parallel mode...opening the files\n"); */ - /* disable error reporting */ H5E_BEGIN_TRY { @@ -179,9 +179,38 @@ ph5diff_worker(int nID) /*Wait for print token. */ MPI_Recv(NULL, 0, MPI_BYTE, 0, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD, &Status); - - /*When get token, print stuff out and return token */ - printf("%s", outBuff); + + /*When get token, send all of our output to the manager task and then return the token */ + for(i=0; i<outBuffOffset; i+=PRINT_DATA_MAX_SIZE) + MPI_Send(outBuff+i, PRINT_DATA_MAX_SIZE, MPI_BYTE, 0, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD); + + + /* An overflow file exists, so we send it's output to the manager too and then delete it */ + if(overflow_file) + { + int tmp; + memset(out_data, 0, PRINT_DATA_MAX_SIZE); + i=0; + + rewind(overflow_file); + while((tmp = getc(overflow_file)) >= 0) + { + *(out_data + i++) = (char)tmp; + if(i==PRINT_DATA_MAX_SIZE) + { + MPI_Send(out_data, PRINT_DATA_MAX_SIZE, MPI_BYTE, 0, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD); + i=0; + memset(out_data, 0, PRINT_DATA_MAX_SIZE); + } + } + + if(i>0) + MPI_Send(out_data, PRINT_DATA_MAX_SIZE, MPI_BYTE, 0, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD); + + fclose(overflow_file); + overflow_file = NULL; + } + fflush(stdout); memset(outBuff, 0, OUTBUFF_SIZE); outBuffOffset = 0; @@ -196,17 +225,17 @@ ph5diff_worker(int nID) } else MPI_Send(&nfound, sizeof(nfound), MPI_BYTE, 0, MPI_TAG_DONE, MPI_COMM_WORLD); - } else if(Status.MPI_TAG == MPI_TAG_END) { MPI_Recv(NULL, 0, MPI_BYTE, 0, MPI_TAG_END, MPI_COMM_WORLD, &Status); - /* printf("exiting..., task: %d\n", nID); */ + /* printf("exiting..., task: %d\n", nID); + fflush(stdout);*/ break; } else { - printf("ERROR....invalid tag received\n"); + printf("ph5diff_worker: ERROR: invalid tag (%d) received\n", Status.MPI_TAG); MPI_Abort(MPI_COMM_WORLD, 0); } diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index 13e3f4b..f018fb5 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -50,7 +50,6 @@ print_objname (diff_opt_t * options, hsize_t nfound) void phdiff_dismiss_workers(void) { int i; - for(i=1; i<g_nTasks; i++) MPI_Send(NULL, 0, MPI_BYTE, i, MPI_TAG_END, MPI_COMM_WORLD); } @@ -76,16 +75,62 @@ void print_manager_output(void) if( (outBuffOffset>0) && g_Parallel) { printf("%s", outBuff); + + if(overflow_file) + { + int tmp; + + rewind(overflow_file); + while((tmp = getc(overflow_file)) >= 0) + putchar(tmp); + + fclose(overflow_file); + overflow_file = NULL; + } + fflush(stdout); memset(outBuff, 0, OUTBUFF_SIZE); outBuffOffset = 0; } else if( (outBuffOffset>0) && !g_Parallel) { - printf("h5diff error: outBuffOffset>0, but we're not in parallel\n"); + printf("h5diff error: outBuffOffset>0, but we're not in parallel!\n"); } } +/*------------------------------------------------------------------------- + * Function: print_incoming_data + * + * Purpose: special function that prints any output that has been sent to the manager + * and is currently sitting in the incoming message queue + * + * Return: none + * + * Programmer: Leon Arber + * + * Date: March 7, 2005 + * + *------------------------------------------------------------------------- + */ + +static void print_incoming_data(void) +{ + char data[PRINT_DATA_MAX_SIZE+1]; + int incomingMessage; + MPI_Status Status; + + do + { + MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD, &incomingMessage, &Status); + if(incomingMessage) + { + memset(data, 0, PRINT_DATA_MAX_SIZE+1); + MPI_Recv(data, PRINT_DATA_MAX_SIZE, MPI_CHAR, Status.MPI_SOURCE, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD, &Status); + + printf("%s", data); + } + } while(incomingMessage); +} #endif /*------------------------------------------------------------------------- @@ -237,8 +282,7 @@ h5diff (const char *fname1, if(g_Parallel) { /* Let tasks know that they won't be needed */ - for(i=1; i<g_nTasks; i++) - MPI_Send(filenames, 1024*2, MPI_CHAR, i, MPI_TAG_END, MPI_COMM_WORLD); + phdiff_dismiss_workers(); } #endif assert (objname2); @@ -246,10 +290,6 @@ h5diff (const char *fname1, nfound = diff_compare (file1_id, fname1, objname1, nobjects1, info1, file2_id, fname2, objname2, nobjects2, info2, options); -#ifdef H5_HAVE_PARALLEL - /* If there was something we buffered, let's print it now */ - print_manager_output(); -#endif } /*------------------------------------------------------------------------- @@ -494,7 +534,6 @@ diff_match (hid_t file1_id, /* check to see if the print token was returned. */ if(!havePrintToken) { - /* check incoming queue for token */ MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &incomingMessage, &Status); @@ -521,6 +560,9 @@ diff_match (hid_t file1_id, havePrintToken = 0; } } + + /* Print all the data in our incoming queue */ + print_incoming_data(); } /* check array of tasks to see which ones are free. @@ -551,28 +593,19 @@ diff_match (hid_t file1_id, * if we don't have the token, some task is currently printing so we'll wait for that task to return it. */ if(!havePrintToken) { - MPI_Probe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); - - if(Status.MPI_TAG == MPI_TAG_TOK_RETURN) - { - MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); - havePrintToken = 1; - nfound += nFoundbyWorker; - /* send this task the work unit. */ - MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, MPI_COMM_WORLD); - } - else - { - printf("ERROR: Invalid (%d) tag received\n", Status.MPI_TAG); - MPI_Abort(MPI_COMM_WORLD, 0); - MPI_Finalize(); - } + MPI_Recv(&nFoundbyWorker, sizeof(hsize_t), MPI_BYTE, MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status); + havePrintToken = 1; + nfound += nFoundbyWorker; + /* send this task the work unit. */ + MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, MPI_COMM_WORLD); } /* if we do have the token, check for task to free up, or wait for a task to request it */ else { - MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status); + /* But first print all the data in our incoming queue */ + print_incoming_data(); + MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status); if(Status.MPI_TAG == MPI_TAG_DONE) { MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status); @@ -595,9 +628,6 @@ diff_match (hid_t file1_id, MPI_Finalize(); } } - - - } } #endif @@ -612,9 +642,16 @@ diff_match (hid_t file1_id, MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status); if(Status.MPI_TAG == MPI_TAG_DONE) { + MPI_Recv(&nFoundbyWorker, sizeof(hsize_t), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status); + nfound += nFoundbyWorker; + busyTasks--; + } + else if(Status.MPI_TAG == MPI_TAG_TOK_RETURN) + { MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status); nfound += nFoundbyWorker; busyTasks--; + havePrintToken = 1; } else if(Status.MPI_TAG == MPI_TAG_TOK_REQUEST) { @@ -642,15 +679,28 @@ diff_match (hid_t file1_id, busyTasks--; havePrintToken = 1; } + else if(Status.MPI_TAG == MPI_TAG_PRINT_DATA) + { + char data[PRINT_DATA_MAX_SIZE+1]; + memset(data, 0, PRINT_DATA_MAX_SIZE+1); + + MPI_Recv(data, PRINT_DATA_MAX_SIZE, MPI_CHAR, Status.MPI_SOURCE, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD, &Status); + + printf("%s", data); + } else { - printf("ERROR!! Invalid tag (%d) received \n", Status.MPI_TAG); + printf("ph5diff-manager: ERROR!! Invalid tag (%d) received \n", Status.MPI_TAG); MPI_Abort(MPI_COMM_WORLD, 0); } } for(i=1; i<g_nTasks; i++) MPI_Send(NULL, 0, MPI_BYTE, i, MPI_TAG_END, MPI_COMM_WORLD); + + /* Print any final data waiting in our queue */ + print_incoming_data(); + } free(workerTasks); @@ -669,10 +719,6 @@ diff_match (hid_t file1_id, /* the manager can do this. */ nfound += diff (file1_id, "/", file2_id, "/", options, H5G_GROUP); -#ifdef H5_HAVE_PARALLEL - /* If there was something we buffered, let's print it now */ - print_manager_output(); -#endif return nfound; } @@ -712,13 +758,13 @@ diff_compare (hid_t file1_id, if (i == -1) { - printf ("Object <%s> could not be found in <%s>\n", obj1_name, + parallel_print ("Object <%s> could not be found in <%s>\n", obj1_name, file1_name); f1 = 1; } if (j == -1) { - printf ("Object <%s> could not be found in <%s>\n", obj2_name, + parallel_print ("Object <%s> could not be found in <%s>\n", obj2_name, file2_name); f2 = 1; } @@ -736,7 +782,7 @@ diff_compare (hid_t file1_id, if (info1[i].type != info2[j].type) { if (options->m_verbose) - printf + parallel_print ("Comparison not possible: <%s> is of type %s and <%s> is of type %s\n", obj1_name, get_type (info1[i].type), obj2_name, get_type (info2[j].type)); @@ -797,7 +843,7 @@ diff (hid_t file1_id, if (options->m_verbose) { if (print_objname (options, (hsize_t)1)) - parallel_print("Dataset: <%s> and <%s>\n", path1, path2); + parallel_print("Dataset: <%s> and <%s>\n", path1, path2); nfound = diff_dataset (file1_id, file2_id, path1, path2, options); } diff --git a/tools/lib/h5diff_util.c b/tools/lib/h5diff_util.c index 96d7b5e..c55028c 100644 --- a/tools/lib/h5diff_util.c +++ b/tools/lib/h5diff_util.c @@ -21,6 +21,7 @@ int g_nTasks = 1; unsigned char g_Parallel = 0; /*0 for serial, 1 for parallel */ char outBuff[OUTBUFF_SIZE]; unsigned int outBuffOffset; +FILE* overflow_file = NULL; /*------------------------------------------------------------------------- * Function: parallel_print @@ -35,21 +36,46 @@ unsigned int outBuffOffset; */ void parallel_print(const char* format, ...) { + int bytes_written; va_list ap; va_start(ap, format); if(!g_Parallel) - vprintf(format, ap); + vprintf(format, ap); else { - if((OUTBUFF_SIZE-outBuffOffset) > 0) - outBuffOffset += HDvsnprintf(outBuff+outBuffOffset, OUTBUFF_SIZE-outBuffOffset, format, ap); + + if(overflow_file == NULL) /*no overflow has occurred yet */ + { + bytes_written = HDvsnprintf(outBuff+outBuffOffset, OUTBUFF_SIZE-outBuffOffset, format, ap); + + va_end(ap); + va_start(ap, format); + + if(bytes_written >= (OUTBUFF_SIZE-outBuffOffset)) + { + /* Delete the characters that were written to outBuff since they will be written to the overflow_file */ + memset(outBuff+outBuffOffset, 0, OUTBUFF_SIZE - outBuffOffset); + + overflow_file = tmpfile(); + + if(overflow_file == NULL) + printf("Warning: Could not create overflow file. Output may be truncated.\n"); + else + bytes_written = HDvfprintf(overflow_file, format, ap); + } + else + outBuffOffset += bytes_written; + } + else + bytes_written = HDvfprintf(overflow_file, format, ap); + + } va_end(ap); } - /*------------------------------------------------------------------------- * Function: print_pos * @@ -110,7 +136,7 @@ void print_pos( int *ph, for ( i = 0; i < rank; i++) { /* HDfprintf(stdout,"%Hu ", pos[i] ); */ - parallel_print("%d ",(int) pos[i]); + parallel_print("%"H5_PRINTF_LL_WIDTH"u ", pos[i]); } parallel_print("]" ); } @@ -377,7 +403,7 @@ get_class(H5T_class_t tclass) void print_found(hsize_t nfound) { if(g_Parallel) - outBuffOffset += HDsnprintf(outBuff+outBuffOffset, OUTBUFF_SIZE-outBuffOffset, "%lld differences found\n", nfound); + parallel_print("%"H5_PRINTF_LL_WIDTH"u differences found\n", nfound); else HDfprintf(stdout,"%Hu differences found\n",nfound); } diff --git a/tools/lib/ph5diff.h b/tools/lib/ph5diff.h index 91d7050..44e5b26 100644 --- a/tools/lib/ph5diff.h +++ b/tools/lib/ph5diff.h @@ -16,7 +16,8 @@ #define _PH5DIFF_H__ -#define OUTBUFF_SIZE 50000 +#define PRINT_DATA_MAX_SIZE 512 +#define OUTBUFF_SIZE PRINT_DATA_MAX_SIZE*2 /* Send from manager to workers */ #define MPI_TAG_ARGS 1 #define MPI_TAG_PRINT_TOK 2 @@ -25,15 +26,17 @@ #define MPI_TAG_TOK_REQUEST 3 #define MPI_TAG_DONE 4 #define MPI_TAG_TOK_RETURN 5 +#define MPI_TAG_PRINT_DATA 6 /* Operational tags used to init and complete diff */ -#define MPI_TAG_END 6 -#define MPI_TAG_PARALLEL 7 +#define MPI_TAG_END 7 +#define MPI_TAG_PARALLEL 8 extern int g_nTasks; extern unsigned char g_Parallel; -extern char outBuff[OUTBUFF_SIZE]; +extern char outBuff[]; extern unsigned int outBuffOffset; +extern FILE* overflow_file; struct diff_args { |