diff options
-rw-r--r-- | tools/h5diff/h5diff_main.c | 15 | ||||
-rw-r--r-- | tools/lib/h5diff.c | 314 | ||||
-rw-r--r-- | tools/lib/h5diff.h | 15 | ||||
-rw-r--r-- | tools/lib/h5diff_util.c | 2 | ||||
-rw-r--r-- | tools/lib/ph5diff.h | 6 |
5 files changed, 334 insertions, 18 deletions
diff --git a/tools/h5diff/h5diff_main.c b/tools/h5diff/h5diff_main.c index bab980a..d25904f 100644 --- a/tools/h5diff/h5diff_main.c +++ b/tools/h5diff/h5diff_main.c @@ -73,13 +73,6 @@ int main(int argc, const char *argv[]) MPI_Comm_rank(MPI_COMM_WORLD, &nID); MPI_Comm_size(MPI_COMM_WORLD, &g_nTasks); - if(g_nTasks < 2) - { - printf("Must have at least 2 tasks to run parallel diff\n"); - MPI_Finalize(); - exit(-1); - } - /* Have the manager process the command-line */ if(nID == 0) { @@ -224,10 +217,14 @@ int main(int argc, const char *argv[]) }/*for*/ - nfound = h5diff(fname1,fname2,objname1,objname2,&options); + if(g_nTasks < 2) + nfound = h5diff(fname1,fname2,objname1,objname2,&options); + else + nfound = h5diff_parallel(fname1,fname2,objname1,objname2,&options); #ifdef H5_HAVE_PH5DIFF - MPI_Barrier(MPI_COMM_WORLD); + if(g_nTasks > 1) + MPI_Barrier(MPI_COMM_WORLD); #endif /*------------------------------------------------------------------------- diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index 1807f4b..0b8bb7e 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -33,6 +33,7 @@ print_objname (diff_opt_t * options, hsize_t nfound) return ((options->m_verbose || nfound) && !options->m_quiet) ? 1 : 0; } + /*------------------------------------------------------------------------- * Function: h5diff * @@ -85,6 +86,313 @@ h5diff (const char *fname1, printf ("h5diff: <%s>: unable to open file\n", fname1); options->err_stat = 1; + goto out; + } + if ((file2_id = H5Fopen (fname2, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + { + printf ("h5diff: <%s>: unable to open file\n", fname2); + options->err_stat = 1; + + goto out; + } + /* enable error reporting */ + } + H5E_END_TRY; + + +/*------------------------------------------------------------------------- + * get the number of objects in the files + *------------------------------------------------------------------------- + */ + nobjects1 = h5trav_getinfo (file1_id, NULL, 0); + nobjects2 = h5trav_getinfo (file2_id, NULL, 0); + + if (nobjects1 < 0 || nobjects2 < 0) + { + printf ("Error: Could not get get file contents\n"); + options->err_stat = 1; + goto out; + } + + assert (nobjects1 > 0); + assert (nobjects2 > 0); + +/*------------------------------------------------------------------------- + * get the list of objects in the files + *------------------------------------------------------------------------- + */ + + info1 = (trav_info_t *) malloc (nobjects1 * sizeof (trav_info_t)); + info2 = (trav_info_t *) malloc (nobjects2 * sizeof (trav_info_t)); + if (info1 == NULL || info2 == NULL) + { + printf ("Error: Not enough memory for object list\n"); + options->err_stat = 1; + if (info1) + h5trav_freeinfo (info1, nobjects1); + if (info2) + h5trav_freeinfo (info2, nobjects1); + goto out; + } + + h5trav_getinfo (file1_id, info1, 0); + h5trav_getinfo (file2_id, info2, 0); + +/*------------------------------------------------------------------------- + * object name was supplied + *------------------------------------------------------------------------- + */ + + if (objname1) + { + + assert (objname2); + options->cmn_objs = 1; /* eliminate warning */ + nfound = diff_compare (file1_id, fname1, objname1, nobjects1, info1, + file2_id, fname2, objname2, nobjects2, info2, + options); + } + +/*------------------------------------------------------------------------- + * compare all + *------------------------------------------------------------------------- + */ + + else + { + + nfound = diff_match (file1_id, nobjects1, info1, + file2_id, nobjects2, info2, options); + } + + + h5trav_freeinfo (info1, nobjects1); + h5trav_freeinfo (info2, nobjects2); + +out: + /* close */ + H5E_BEGIN_TRY + { + H5Fclose (file1_id); + H5Fclose (file2_id); + } + H5E_END_TRY; + + return nfound; +} + + + +/*------------------------------------------------------------------------- + * Function: diff_match + * + * Purpose: Find common objects; the algorithm used for this search is the + * cosequential match algorithm and is described in + * Folk, Michael; Zoellick, Bill. (1992). File Structures. Addison-Wesley. + * + * Return: Number of differences found + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: May 9, 2003 + * + *------------------------------------------------------------------------- + */ +hsize_t +diff_match (hid_t file1_id, + int nobjects1, + trav_info_t * info1, + hid_t file2_id, + int nobjects2, trav_info_t * info2, diff_opt_t * options) +{ + int more_names_exist = (nobjects1 > 0 && nobjects2 > 0) ? 1 : 0; + trav_table_t *table = NULL; + int cmp; + int curr1 = 0; + int curr2 = 0; + unsigned infile[2]; + char c1, c2; + hsize_t nfound = 0; + int i; + + /*------------------------------------------------------------------------- + * build the list + *------------------------------------------------------------------------- + */ + trav_table_init (&table); + + while (more_names_exist) + { + /* criteria is string compare */ + cmp = strcmp (info1[curr1].name, info2[curr2].name); + if (cmp == 0) + { + infile[0] = 1; + infile[1] = 1; + trav_table_addflags (infile, info1[curr1].name, info1[curr1].type, + table); + + curr1++; + curr2++; + } + else if (cmp < 0) + { + infile[0] = 1; + infile[1] = 0; + trav_table_addflags (infile, info1[curr1].name, info1[curr1].type, + table); + curr1++; + } + else + { + infile[0] = 0; + infile[1] = 1; + trav_table_addflags (infile, info2[curr2].name, info2[curr2].type, + table); + curr2++; + } + + more_names_exist = (curr1 < nobjects1 && curr2 < nobjects2) ? 1 : 0; + + + } /* end while */ + + /* list1 did not end */ + if (curr1 < nobjects1) + { + while (curr1 < nobjects1) + { + infile[0] = 1; + infile[1] = 0; + trav_table_addflags (infile, info1[curr1].name, info1[curr1].type, + table); + curr1++; + } + } + + /* list2 did not end */ + if (curr2 < nobjects2) + { + while (curr2 < nobjects2) + { + infile[0] = 0; + infile[1] = 1; + trav_table_addflags (infile, info2[curr2].name, info2[curr2].type, + table); + curr2++; + } + } + + /*------------------------------------------------------------------------- + * print the list + *------------------------------------------------------------------------- + */ + + if (options->m_verbose) + { + printf ("\n"); + printf ("file1 file2\n"); + printf ("---------------------------------------\n"); + for (i = 0; i < table->nobjs; i++) + { + c1 = (table->objs[i].flags[0]) ? 'x' : ' '; + c2 = (table->objs[i].flags[1]) ? 'x' : ' '; + printf ("%5c %6c %-15s\n", c1, c2, table->objs[i].name); + } + printf ("\n"); + } + + + /*------------------------------------------------------------------------- + * do the diff for common objects + *------------------------------------------------------------------------- + */ + + for (i = 0; i < table->nobjs; i++) + { + if (table->objs[i].flags[0] && table->objs[i].flags[1]) + { + int workerFound = 0; + options->cmn_objs = 1; + nfound += diff (file1_id, + table->objs[i].name, + file2_id, + table->objs[i].name, options, table->objs[i].type); + } + + } + /* free table */ + trav_table_free (table); + + + /*------------------------------------------------------------------------- + * do the diff for the root. + * this is a special case, we get an ID for the root group and call diff() + * with this ID; it compares only the root group attributes + *------------------------------------------------------------------------- + */ + + /* the manager can do this. */ + nfound += diff (file1_id, "/", file2_id, "/", options, H5G_GROUP); + + return nfound; +} + + + + +/*------------------------------------------------------------------------- + * Function: h5diff_parallel + * + * Purpose: public function, can be called in an application program. + * return differences between 2 HDF5 files + * + * Return: Number of differences found. + * + * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * + * Date: October 22, 2003 + * + *------------------------------------------------------------------------- + */ + +hsize_t +h5diff_parallel (const char *fname1, + const char *fname2, + const char *objname1, const char *objname2, diff_opt_t * options) +{ + int nobjects1, nobjects2, i; + trav_info_t *info1 = NULL; + trav_info_t *info2 = NULL; + hid_t file1_id=(-1), file2_id=(-1); + char filenames[2][255]; + hsize_t nfound = 0; + + memset(filenames, 0, 255*2); + + + if (options->m_quiet && (options->m_verbose || options->m_report)) + { + printf + ("Error: -q (quiet mode) cannot be added to verbose or report modes\n"); + options->err_stat = 1; + return 0; + } + +/*------------------------------------------------------------------------- + * open the files first; if they are not valid, no point in continuing + *------------------------------------------------------------------------- + */ + + /* disable error reporting */ + H5E_BEGIN_TRY + { + /* Open the files */ + if ((file1_id = H5Fopen (fname1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + { + printf ("h5diff: <%s>: unable to open file\n", fname1); + options->err_stat = 1; + #ifdef H5_HAVE_PH5DIFF /* Let tasks know that they won't be needed */ for(i=1; i<g_nTasks; i++) @@ -186,7 +494,7 @@ h5diff (const char *fname1, for(i=1; i<g_nTasks; i++) MPI_Send(filenames, 255*2, MPI_CHAR, i, MPI_TAG_PARALLEL, MPI_COMM_WORLD); #endif - nfound = diff_match (file1_id, nobjects1, info1, + nfound = diff_match_parallel (file1_id, nobjects1, info1, file2_id, nobjects2, info2, options); } @@ -209,7 +517,7 @@ out: /*------------------------------------------------------------------------- - * Function: diff_match + * Function: diff_match_parallel * * Purpose: Find common objects; the algorithm used for this search is the * cosequential match algorithm and is described in @@ -224,7 +532,7 @@ out: *------------------------------------------------------------------------- */ hsize_t -diff_match (hid_t file1_id, +diff_match_parallel (hid_t file1_id, int nobjects1, trav_info_t * info1, hid_t file2_id, diff --git a/tools/lib/h5diff.h b/tools/lib/h5diff.h index f69719f..5b351ba 100644 --- a/tools/lib/h5diff.h +++ b/tools/lib/h5diff.h @@ -82,6 +82,13 @@ hsize_t h5diff(const char *fname1, const char *objname2, diff_opt_t *options); +hsize_t h5diff_parallel(const char *fname1, + const char *fname2, + const char *objname1, + const char *objname2, + diff_opt_t *options); + + #ifdef __cplusplus } @@ -134,6 +141,14 @@ hsize_t diff_match( hid_t file1_id, trav_info_t *info2, diff_opt_t *options ); +hsize_t diff_match_parallel( hid_t file1_id, + int nobjects1, + trav_info_t *info1, + hid_t file2_id, + int nobjects2, + trav_info_t *info2, + diff_opt_t *options ); + hsize_t diff_array( void *_mem1, void *_mem2, hsize_t nelmts, diff --git a/tools/lib/h5diff_util.c b/tools/lib/h5diff_util.c index 416e808..bc66378 100644 --- a/tools/lib/h5diff_util.c +++ b/tools/lib/h5diff_util.c @@ -34,7 +34,7 @@ void parallel_print(const char* format, ...) va_start(ap, format); - if(!PARALLEL) + if(g_nTasks < 2) vprintf(format, ap); else outBuffOffset += vsnprintf(outBuff+outBuffOffset, OUTBUFF_SIZE-outBuffOffset, format, ap); diff --git a/tools/lib/ph5diff.h b/tools/lib/ph5diff.h index cb28001..68450df 100644 --- a/tools/lib/ph5diff.h +++ b/tools/lib/ph5diff.h @@ -34,7 +34,6 @@ int g_nTasks; char outBuff[OUTBUFF_SIZE]; unsigned int outBuffOffset; - struct diff_args { char name[256]; @@ -45,12 +44,9 @@ struct diff_args #ifdef H5_HAVE_PARALLEL #define H5_HAVE_PH5DIFF 1 #endif + #ifdef H5_HAVE_PH5DIFF -#define PARALLEL 1 #include <mpi.h> - -#else -#define PARALLEL 0 #endif |