summaryrefslogtreecommitdiffstats
path: root/tools/lib/h5diff.c
diff options
context:
space:
mode:
authorLeon Arber <larber@ncsa.uiuc.edu>2005-02-02 23:01:42 (GMT)
committerLeon Arber <larber@ncsa.uiuc.edu>2005-02-02 23:01:42 (GMT)
commit8af13859397ca1030dda5668017664692669d7e6 (patch)
treed938619dd7e386fa443986cea5700551925ee618 /tools/lib/h5diff.c
parentd0ced67f526acb4491269e8e66799e9fb81115ac (diff)
downloadhdf5-8af13859397ca1030dda5668017664692669d7e6.zip
hdf5-8af13859397ca1030dda5668017664692669d7e6.tar.gz
hdf5-8af13859397ca1030dda5668017664692669d7e6.tar.bz2
[svn-r9925] Purpose:
Bug Fix Description: Permanent fix for the incompatibilities between h5diff and h5repack. Solution: h5diff now contains the code to run both parallel and serial diffs. Depending on how the binary is called, it will run either the serial or the parallel versions respectively. Platforms tested: heping(serial + parallel), copper. Misc. update:
Diffstat (limited to 'tools/lib/h5diff.c')
-rw-r--r--tools/lib/h5diff.c660
1 files changed, 196 insertions, 464 deletions
diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c
index 0b8bb7e..39be45b 100644
--- a/tools/lib/h5diff.c
+++ b/tools/lib/h5diff.c
@@ -46,6 +46,9 @@ print_objname (diff_opt_t * options, hsize_t nfound)
*
* Date: October 22, 2003
*
+ * Modifications: Jan 2005 Leon Arber, larber@uiuc.edu
+ * Added support for parallel diffing
+ *
*-------------------------------------------------------------------------
*/
@@ -58,10 +61,10 @@ h5diff (const char *fname1,
trav_info_t *info1 = NULL;
trav_info_t *info2 = NULL;
hid_t file1_id=(-1), file2_id=(-1);
- char filenames[2][255];
+ char filenames[2][1024];
hsize_t nfound = 0;
- memset(filenames, 0, 255*2);
+ memset(filenames, 0, 1024*2);
if (options->m_quiet && (options->m_verbose || options->m_report))
@@ -86,317 +89,13 @@ 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)
+#ifdef H5_HAVE_PARALLEL
+ if(g_Parallel)
{
- infile[0] = 1;
- infile[1] = 1;
- trav_table_addflags (infile, info1[curr1].name, info1[curr1].type,
- table);
-
- curr1++;
- curr2++;
+ /* 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);
}
- 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++)
- MPI_Send(filenames, 255*2, MPI_CHAR, i, MPI_TAG_END, MPI_COMM_WORLD);
#endif
goto out;
@@ -406,10 +105,13 @@ h5diff_parallel (const char *fname1,
printf ("h5diff: <%s>: unable to open file\n", fname2);
options->err_stat = 1;
-#ifdef H5_HAVE_PH5DIFF
- /* Let tasks know that they won't be needed */
- for(i=1; i<g_nTasks; i++)
- MPI_Send(filenames, 255*2, MPI_CHAR, i, MPI_TAG_END, MPI_COMM_WORLD);
+#ifdef H5_HAVE_PARALLEL
+ 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);
+ }
#endif
goto out;
@@ -465,10 +167,13 @@ h5diff_parallel (const char *fname1,
if (objname1)
{
-#ifdef H5_HAVE_PH5DIFF
- /* Let tasks know that they won't be needed */
- for(i=1; i<g_nTasks; i++)
- MPI_Send(filenames, 255*2, MPI_CHAR, i, MPI_TAG_END, MPI_COMM_WORLD);
+#ifdef H5_HAVE_PARALLEL
+ 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);
+ }
#endif
assert (objname2);
options->cmn_objs = 1; /* eliminate warning */
@@ -485,16 +190,25 @@ h5diff_parallel (const char *fname1,
else
{
-#ifdef H5_HAVE_PH5DIFF
- strncpy(filenames[0], fname1, 255);
- strncpy(filenames[1], fname2, 255);
-
- /* Alert the worker tasks that there's going to be work. */
+#ifdef H5_HAVE_PARALLEL
+ if(g_Parallel)
+ {
+ if( (strlen(fname1) > 1024) || (strlen(fname2) > 1024))
+ {
+ printf("The parallel diff only supports path names up to 1024 characters\n");
+ MPI_Abort(MPI_COMM_WORLD, 0);
+ }
+
+ strcpy(filenames[0], fname1);
+ strcpy(filenames[1], fname2);
- for(i=1; i<g_nTasks; i++)
- MPI_Send(filenames, 255*2, MPI_CHAR, i, MPI_TAG_PARALLEL, MPI_COMM_WORLD);
+ /* Alert the worker tasks that there's going to be work. */
+
+ for(i=1; i<g_nTasks; i++)
+ MPI_Send(filenames, 1024*2, MPI_CHAR, i, MPI_TAG_PARALLEL, MPI_COMM_WORLD);
+ }
#endif
- nfound = diff_match_parallel (file1_id, nobjects1, info1,
+ nfound = diff_match (file1_id, nobjects1, info1,
file2_id, nobjects2, info2, options);
}
@@ -517,7 +231,7 @@ out:
/*-------------------------------------------------------------------------
- * Function: diff_match_parallel
+ * Function: diff_match
*
* Purpose: Find common objects; the algorithm used for this search is the
* cosequential match algorithm and is described in
@@ -528,11 +242,14 @@ out:
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
* Date: May 9, 2003
+ *
+ * Modifications: Jan 2005 Leon Arber, larber@uiuc.edu
+ * Added support for parallel diffing
*
*-------------------------------------------------------------------------
*/
hsize_t
-diff_match_parallel (hid_t file1_id,
+diff_match (hid_t file1_id,
int nobjects1,
trav_info_t * info1,
hid_t file2_id,
@@ -641,8 +358,7 @@ diff_match_parallel (hid_t file1_id,
*-------------------------------------------------------------------------
*/
{
-#ifdef H5_HAVE_PH5DIFF
- /*SEND NAMES/OBJS OFF TO WORKER TASKS FOR DIFF'ING HERE */
+#ifdef H5_HAVE_PARALLEL
char* workerTasks = malloc((g_nTasks-1) * sizeof(char));
int n;
int busyTasks=0;
@@ -661,191 +377,207 @@ diff_match_parallel (hid_t file1_id,
{
int workerFound = 0;
options->cmn_objs = 1;
-#ifndef H5_HAVE_PH5DIFF
- nfound += diff (file1_id,
- table->objs[i].name,
- file2_id,
- table->objs[i].name, options, table->objs[i].type);
-#else
- /* We're in parallel mode */
-
- /*Set up args to pass to worker task. */
- strncpy(args.name, table->objs[i].name, 255);
- args.options = *options;
- args.type= table->objs[i].type;
-
- /* if there are any outstanding print requests, let's handle one. */
- if(busyTasks > 0)
+ if(!g_Parallel)
+ {
+ nfound += diff (file1_id,
+ table->objs[i].name,
+ file2_id,
+ table->objs[i].name, options, table->objs[i].type);
+ }
+#ifdef H5_HAVE_PARALLEL
+ else
{
- int incomingMessage;
- /* check if any tasks freed up, and didn't need to print. */
- MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &incomingMessage, &Status);
+ /* We're in parallel mode */
- if(incomingMessage)
+ /*Set up args to pass to worker task. */
+ if(strlen(table->objs[i].name) > 255)
{
- workerTasks[Status.MPI_SOURCE-1] = 1;
- MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status);
- nfound += nFoundbyWorker;
- busyTasks--;
+ printf("The parallel diff only supports object names up to 255 characters\n");
+ MPI_Abort(MPI_COMM_WORLD, 0);
}
+
+ strcpy(args.name, table->objs[i].name);
+ args.options = *options;
+ args.type= table->objs[i].type;
- /* check to see if the print token was returned. */
- if(!havePrintToken)
+ /* if there are any outstanding print requests, let's handle one. */
+ if(busyTasks > 0)
{
+ int incomingMessage;
+ /* check if any tasks freed up, and didn't need to print. */
+ MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &incomingMessage, &Status);
- /* check incoming queue for token */
- MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &incomingMessage, &Status);
-
- /* incoming token implies free task. */
if(incomingMessage)
{
workerTasks[Status.MPI_SOURCE-1] = 1;
- MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
+ MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status);
nfound += nFoundbyWorker;
busyTasks--;
- havePrintToken = 1;
}
- }
- /* check to see if anyone needs the print token. */
- if(havePrintToken)
- {
- /* check incoming queue for print token requests */
- MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &incomingMessage, &Status);
- if(incomingMessage)
+ /* check to see if the print token was returned. */
+ if(!havePrintToken)
{
- MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &Status);
- MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD);
- havePrintToken = 0;
+
+ /* check incoming queue for token */
+ MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &incomingMessage, &Status);
+
+ /* incoming token implies free task. */
+ if(incomingMessage)
+ {
+ workerTasks[Status.MPI_SOURCE-1] = 1;
+ MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
+ nfound += nFoundbyWorker;
+ busyTasks--;
+ havePrintToken = 1;
+ }
+ }
+
+ /* check to see if anyone needs the print token. */
+ if(havePrintToken)
+ {
+ /* check incoming queue for print token requests */
+ MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &incomingMessage, &Status);
+ if(incomingMessage)
+ {
+ MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &Status);
+ MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD);
+ havePrintToken = 0;
+ }
}
}
- }
- /* check array of tasks to see which ones are free.
- * Manager task never does work, so freeTasks[0] is really
- * worker task 0. */
+ /* check array of tasks to see which ones are free.
+ * Manager task never does work, so freeTasks[0] is really
+ * worker task 0. */
- for(n=1; (n<g_nTasks) && !workerFound; n++)
- {
- if(workerTasks[n-1])
+ for(n=1; (n<g_nTasks) && !workerFound; n++)
{
- /* send file id's and names to first free worker */
- MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, n, MPI_TAG_ARGS, MPI_COMM_WORLD);
+ if(workerTasks[n-1])
+ {
+ /* send file id's and names to first free worker */
+ MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, n, MPI_TAG_ARGS, MPI_COMM_WORLD);
- /* increment counter for total number of prints. */
- busyTasks++;
+ /* increment counter for total number of prints. */
+ busyTasks++;
- /* mark worker as busy */
- workerTasks[n-1] = 0;
- workerFound = 1;
- }
+ /* mark worker as busy */
+ workerTasks[n-1] = 0;
+ workerFound = 1;
+ }
- }
+ }
- if(!workerFound)
- {
- /* if they were all busy, we've got to wait for one free up before we can move on.
- * if we don't have the token, some task is currently printing so we'll wait for that task to return it. */
- if(!havePrintToken)
+ if(!workerFound)
{
- MPI_Probe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
-
- if(Status.MPI_TAG == MPI_TAG_TOK_RETURN)
+ /* if they were all busy, we've got to wait for one free up before we can move on.
+ * 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_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, 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);
+ MPI_Probe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
+
+ if(Status.MPI_TAG == MPI_TAG_TOK_RETURN)
+ {
+ MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, 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();
+ }
}
+ /* if we do have the token, check for task to free up, or wait for a task to request it */
else
{
- printf("ERROR: Invalid (%d) tag received\n", Status.MPI_TAG);
- MPI_Abort(MPI_COMM_WORLD, 0);
- MPI_Finalize();
+ MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
+
+ if(Status.MPI_TAG == MPI_TAG_DONE)
+ {
+ MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status);
+ nfound += nFoundbyWorker;
+ MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, MPI_COMM_WORLD);
+ }
+ else if(Status.MPI_TAG == MPI_TAG_TOK_REQUEST)
+ {
+ MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &Status);
+ MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD);
+
+ MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
+ nfound += nFoundbyWorker;
+ MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, MPI_COMM_WORLD);
+ }
+ else
+ {
+ printf("ERROR: Invalid tag (%d) received \n", Status.MPI_TAG);
+ MPI_Abort(MPI_COMM_WORLD, 0);
+ MPI_Finalize();
+ }
}
- }
- /* 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);
-
- if(Status.MPI_TAG == MPI_TAG_DONE)
- {
- MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status);
- nfound += nFoundbyWorker;
- MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, MPI_COMM_WORLD);
- }
- else if(Status.MPI_TAG == MPI_TAG_TOK_REQUEST)
- {
- MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &Status);
- MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD);
-
- MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
- nfound += nFoundbyWorker;
- MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, MPI_COMM_WORLD);
- }
- else
- {
- printf("ERROR: Invalid tag (%d) received \n", Status.MPI_TAG);
- MPI_Abort(MPI_COMM_WORLD, 0);
- MPI_Finalize();
- }
- }
+ }
}
#endif
}
}
-#ifdef H5_HAVE_PH5DIFF
- while(busyTasks > 0) /* make sure all tasks are done */
+#ifdef H5_HAVE_PARALLEL
+ if(g_Parallel)
{
- MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
- if(Status.MPI_TAG == MPI_TAG_DONE)
- {
- MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status);
- nfound += nFoundbyWorker;
- busyTasks--;
- }
- else if(Status.MPI_TAG == MPI_TAG_TOK_REQUEST)
+ while(busyTasks > 0) /* make sure all tasks are done */
{
- MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &Status);
- if(havePrintToken)
+ MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
+ if(Status.MPI_TAG == MPI_TAG_DONE)
{
- MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD);
- MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
+ MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status);
nfound += nFoundbyWorker;
busyTasks--;
}
- else /* someone else must have it...wait for them to return it, then give it to the task that just asked for it. */
+ else if(Status.MPI_TAG == MPI_TAG_TOK_REQUEST)
+ {
+ MPI_Recv(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_REQUEST, MPI_COMM_WORLD, &Status);
+ if(havePrintToken)
+ {
+ MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD);
+ MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
+ nfound += nFoundbyWorker;
+ busyTasks--;
+ }
+ else /* someone else must have it...wait for them to return it, then give it to the task that just asked for it. */
+ {
+ int source = Status.MPI_SOURCE;
+ MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
+ nfound += nFoundbyWorker;
+ busyTasks--;
+ MPI_Send(NULL, 0, MPI_BYTE, source, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD);
+ }
+ }
+ else if(Status.MPI_TAG == MPI_TAG_TOK_RETURN)
{
- int source = Status.MPI_SOURCE;
- MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
+ MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
nfound += nFoundbyWorker;
busyTasks--;
- MPI_Send(NULL, 0, MPI_BYTE, source, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD);
+ havePrintToken = 1;
+ }
+ else
+ {
+ printf("ERROR!! Invalid tag (%d) received \n", Status.MPI_TAG);
+ MPI_Abort(MPI_COMM_WORLD, 0);
}
}
- else if(Status.MPI_TAG == MPI_TAG_TOK_RETURN)
- {
- MPI_Recv(&nFoundbyWorker, 1, MPI_LONG_LONG, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
- nfound += nFoundbyWorker;
- busyTasks--;
- havePrintToken = 1;
- }
- else
- {
- printf("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);
}
- for(i=1; i<g_nTasks; i++)
- MPI_Send(NULL, 0, MPI_BYTE, i, MPI_TAG_END, MPI_COMM_WORLD);
+ free(workerTasks);
#endif
}
/* free table */