summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/h5diff/h5diff_main.c15
-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
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