diff options
author | Leon Arber <larber@ncsa.uiuc.edu> | 2005-01-27 23:21:05 (GMT) |
---|---|---|
committer | Leon Arber <larber@ncsa.uiuc.edu> | 2005-01-27 23:21:05 (GMT) |
commit | 839f1092da94c17b5f541acdd899e00bc13ef31f (patch) | |
tree | 6e3bae867ebceee26ba4c196bee86973456e5858 /tools/lib/h5diff.c | |
parent | 046fe35568d6393cf887b9d6e9e95ccd36917b4a (diff) | |
download | hdf5-839f1092da94c17b5f541acdd899e00bc13ef31f.zip hdf5-839f1092da94c17b5f541acdd899e00bc13ef31f.tar.gz hdf5-839f1092da94c17b5f541acdd899e00bc13ef31f.tar.bz2 |
[svn-r9877] Purpose:
Bug fix: Temporary fix for h5repack failures in all parallel builds.
Description:
The parallel additions to h5diff interfered with h5repack.
Solution:
Added a second set of "parallel" functions to h5diff.c. h5repack uses the serial versions, whereas h5diff will use the parallel versions.
Also, h5diff will now be smart about when to enter parallel mode. If is run with mpirun with more than 1 task, it will enter parallel mode. Otherwise, it will stay in serial mode as before.
Platforms tested:
heping (serial and parallel)
Misc. update:
Diffstat (limited to 'tools/lib/h5diff.c')
-rw-r--r-- | tools/lib/h5diff.c | 314 |
1 files changed, 311 insertions, 3 deletions
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, |