summaryrefslogtreecommitdiffstats
path: root/tools/lib
diff options
context:
space:
mode:
authorLeon Arber <larber@ncsa.uiuc.edu>2005-01-27 23:21:05 (GMT)
committerLeon Arber <larber@ncsa.uiuc.edu>2005-01-27 23:21:05 (GMT)
commit839f1092da94c17b5f541acdd899e00bc13ef31f (patch)
tree6e3bae867ebceee26ba4c196bee86973456e5858 /tools/lib
parent046fe35568d6393cf887b9d6e9e95ccd36917b4a (diff)
downloadhdf5-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')
-rw-r--r--tools/lib/h5diff.c314
-rw-r--r--tools/lib/h5diff.h15
-rw-r--r--tools/lib/h5diff_util.c2
-rw-r--r--tools/lib/ph5diff.h6
4 files changed, 328 insertions, 9 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,
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