2003-04-03 02:44:12 +08:00
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
* Copyright by the Board of Trustees of the University of Illinois. *
|
|
|
|
* All rights reserved. *
|
|
|
|
* *
|
|
|
|
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
|
|
|
* terms governing use, modification, and redistribution, is contained in *
|
|
|
|
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
|
|
|
* of the source code distribution tree; Copyright.html can be found at the *
|
|
|
|
* root level of an installed copy of the electronic HDF5 document set and *
|
|
|
|
* is linked from the top-level documents page. It can also be found at *
|
|
|
|
* http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
|
|
|
|
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
|
|
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
|
2004-04-18 12:10:09 +08:00
|
|
|
#include <stdlib.h>
|
2003-10-23 05:30:19 +08:00
|
|
|
#include "h5diff.h"
|
2005-01-27 07:03:29 +08:00
|
|
|
#include "H5private.h"
|
|
|
|
#include "ph5diff.h"
|
2002-10-10 00:33:05 +08:00
|
|
|
|
2005-08-19 03:37:32 +08:00
|
|
|
/*
|
|
|
|
* Debug printf macros. The prefix allows output filtering by test scripts.
|
|
|
|
*/
|
2005-08-20 23:15:25 +08:00
|
|
|
#ifdef debug
|
2005-08-19 03:37:32 +08:00
|
|
|
#define h5diffdebug(x) fprintf(stderr, "h5diff debug: " x)
|
|
|
|
#define h5diffdebug2(x1, x2) fprintf(stderr, "h5diff debug: " x1, x2)
|
|
|
|
#define h5diffdebug3(x1, x2, x3) fprintf(stderr, "h5diff debug: " x1, x2, x3)
|
|
|
|
#define h5diffdebug4(x1, x2, x3, x4) fprintf(stderr, "h5diff debug: " x1, x2, x3, x4)
|
|
|
|
#define h5diffdebug5(x1, x2, x3, x4, x5) fprintf(stderr, "h5diff debug: " x1, x2, x3, x4, x5)
|
2005-08-20 23:15:25 +08:00
|
|
|
#else
|
|
|
|
#define h5diffdebug(x)
|
2005-08-22 23:55:54 +08:00
|
|
|
#define h5diffdebug2(x1, x2)
|
|
|
|
#define h5diffdebug3(x1, x2, x3)
|
|
|
|
#define h5diffdebug4(x1, x2, x3, x4)
|
|
|
|
#define h5diffdebug5(x1, x2, x3, x4, x5)
|
2005-08-20 23:15:25 +08:00
|
|
|
#endif
|
2004-07-21 03:21:03 +08:00
|
|
|
|
2005-06-29 00:25:42 +08:00
|
|
|
|
2004-07-21 03:21:03 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* Function: print_objname
|
|
|
|
*
|
|
|
|
* Purpose: print object name only when:
|
|
|
|
* 1) verbose mode
|
|
|
|
* 2) when diff was found (normal mode)
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2005-01-27 07:03:29 +08:00
|
|
|
int
|
|
|
|
print_objname (diff_opt_t * options, hsize_t nfound)
|
2004-07-21 03:21:03 +08:00
|
|
|
{
|
2005-01-27 07:03:29 +08:00
|
|
|
return ((options->m_verbose || nfound) && !options->m_quiet) ? 1 : 0;
|
2004-07-21 03:21:03 +08:00
|
|
|
}
|
|
|
|
|
2005-02-08 13:42:49 +08:00
|
|
|
#ifdef H5_HAVE_PARALLEL
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* Function: phdiff_dismiss_workers
|
|
|
|
*
|
|
|
|
* Purpose: tell all workers to end.
|
|
|
|
*
|
|
|
|
* Return: none
|
|
|
|
*
|
|
|
|
* Programmer: Albert Cheng
|
|
|
|
*
|
|
|
|
* Date: Feb 6, 2005
|
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
void phdiff_dismiss_workers(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for(i=1; i<g_nTasks; i++)
|
2005-06-29 03:20:56 +08:00
|
|
|
MPI_Send(NULL, 0, MPI_BYTE, i, MPI_TAG_END, MPI_COMM_WORLD);
|
2005-02-08 13:42:49 +08:00
|
|
|
}
|
|
|
|
|
2005-02-08 21:42:46 +08:00
|
|
|
|
2005-02-08 13:42:49 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* Function: print_manager_output
|
|
|
|
*
|
|
|
|
* Purpose: special function that prints any output accumulated by the
|
2005-06-29 00:25:42 +08:00
|
|
|
* manager task.
|
2005-02-08 13:42:49 +08:00
|
|
|
*
|
|
|
|
* Return: none
|
|
|
|
*
|
|
|
|
* Programmer: Leon Arber
|
|
|
|
*
|
|
|
|
* Date: Feb 7, 2005
|
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
void print_manager_output(void)
|
|
|
|
{
|
2005-06-29 03:20:56 +08:00
|
|
|
/* If there was something we buffered, let's print it now */
|
|
|
|
if( (outBuffOffset>0) && g_Parallel)
|
|
|
|
{
|
2005-08-14 04:53:35 +08:00
|
|
|
printf("%s", outBuff);
|
[svn-r10170] Purpose:
Bug Fixes
Description:
Fixes for several bugs, including dumping of excess output to a temporary file, fix for printing
hsize_t datatype, and the long awaited fix for intermixed output.
Solution:
Fix 1: Overflow file
Previously, any output that a worker task made was buffered locally in memory, up to a point. Any
output beyond the size of the buffer (used to be 10k) was discarded. Now, the memory buffer size has been
changed to 1k and any output beyond this amount is sent a temporary file. This way, no output is lost
and memory usage is kept under control. The temporary file is deleted as soon as a worker task finishes
sending its contents to the manager.
Fix 2: hsize_t printing
Printing of the hsize_t datatype used to be handled by %Hu passed to HDfprintf. However, there is no corresponding HDvsnprintf that
is able to print hsize_t types. These are now printed with the aid of H5_PRINTF_LL_WIDTH.
Fix 3: Intermixed output fix
Intermixed output would occur on some machines (although I haven't seen it happen for a while) due to the unpredictability of the underlying network
and the speed at which various message would travel. This has been fixed by having all output send to the manager
for printing. The worker tasks no longer print the output themselves upon receipt of a token, but instead
send that data to the manager.
Platforms tested:
heping, eirene, tg-login (the only place that seems to still experience intermixed output every now and then)
Misc. update:
2005-03-10 02:38:36 +08:00
|
|
|
|
2005-06-29 03:20:56 +08:00
|
|
|
if(overflow_file)
|
|
|
|
{
|
|
|
|
int tmp;
|
[svn-r10170] Purpose:
Bug Fixes
Description:
Fixes for several bugs, including dumping of excess output to a temporary file, fix for printing
hsize_t datatype, and the long awaited fix for intermixed output.
Solution:
Fix 1: Overflow file
Previously, any output that a worker task made was buffered locally in memory, up to a point. Any
output beyond the size of the buffer (used to be 10k) was discarded. Now, the memory buffer size has been
changed to 1k and any output beyond this amount is sent a temporary file. This way, no output is lost
and memory usage is kept under control. The temporary file is deleted as soon as a worker task finishes
sending its contents to the manager.
Fix 2: hsize_t printing
Printing of the hsize_t datatype used to be handled by %Hu passed to HDfprintf. However, there is no corresponding HDvsnprintf that
is able to print hsize_t types. These are now printed with the aid of H5_PRINTF_LL_WIDTH.
Fix 3: Intermixed output fix
Intermixed output would occur on some machines (although I haven't seen it happen for a while) due to the unpredictability of the underlying network
and the speed at which various message would travel. This has been fixed by having all output send to the manager
for printing. The worker tasks no longer print the output themselves upon receipt of a token, but instead
send that data to the manager.
Platforms tested:
heping, eirene, tg-login (the only place that seems to still experience intermixed output every now and then)
Misc. update:
2005-03-10 02:38:36 +08:00
|
|
|
|
2005-06-29 03:20:56 +08:00
|
|
|
rewind(overflow_file);
|
|
|
|
while((tmp = getc(overflow_file)) >= 0)
|
|
|
|
putchar(tmp);
|
[svn-r10170] Purpose:
Bug Fixes
Description:
Fixes for several bugs, including dumping of excess output to a temporary file, fix for printing
hsize_t datatype, and the long awaited fix for intermixed output.
Solution:
Fix 1: Overflow file
Previously, any output that a worker task made was buffered locally in memory, up to a point. Any
output beyond the size of the buffer (used to be 10k) was discarded. Now, the memory buffer size has been
changed to 1k and any output beyond this amount is sent a temporary file. This way, no output is lost
and memory usage is kept under control. The temporary file is deleted as soon as a worker task finishes
sending its contents to the manager.
Fix 2: hsize_t printing
Printing of the hsize_t datatype used to be handled by %Hu passed to HDfprintf. However, there is no corresponding HDvsnprintf that
is able to print hsize_t types. These are now printed with the aid of H5_PRINTF_LL_WIDTH.
Fix 3: Intermixed output fix
Intermixed output would occur on some machines (although I haven't seen it happen for a while) due to the unpredictability of the underlying network
and the speed at which various message would travel. This has been fixed by having all output send to the manager
for printing. The worker tasks no longer print the output themselves upon receipt of a token, but instead
send that data to the manager.
Platforms tested:
heping, eirene, tg-login (the only place that seems to still experience intermixed output every now and then)
Misc. update:
2005-03-10 02:38:36 +08:00
|
|
|
|
2005-06-29 03:20:56 +08:00
|
|
|
fclose(overflow_file);
|
|
|
|
overflow_file = NULL;
|
|
|
|
}
|
[svn-r10170] Purpose:
Bug Fixes
Description:
Fixes for several bugs, including dumping of excess output to a temporary file, fix for printing
hsize_t datatype, and the long awaited fix for intermixed output.
Solution:
Fix 1: Overflow file
Previously, any output that a worker task made was buffered locally in memory, up to a point. Any
output beyond the size of the buffer (used to be 10k) was discarded. Now, the memory buffer size has been
changed to 1k and any output beyond this amount is sent a temporary file. This way, no output is lost
and memory usage is kept under control. The temporary file is deleted as soon as a worker task finishes
sending its contents to the manager.
Fix 2: hsize_t printing
Printing of the hsize_t datatype used to be handled by %Hu passed to HDfprintf. However, there is no corresponding HDvsnprintf that
is able to print hsize_t types. These are now printed with the aid of H5_PRINTF_LL_WIDTH.
Fix 3: Intermixed output fix
Intermixed output would occur on some machines (although I haven't seen it happen for a while) due to the unpredictability of the underlying network
and the speed at which various message would travel. This has been fixed by having all output send to the manager
for printing. The worker tasks no longer print the output themselves upon receipt of a token, but instead
send that data to the manager.
Platforms tested:
heping, eirene, tg-login (the only place that seems to still experience intermixed output every now and then)
Misc. update:
2005-03-10 02:38:36 +08:00
|
|
|
|
2005-06-29 03:20:56 +08:00
|
|
|
fflush(stdout);
|
|
|
|
memset(outBuff, 0, OUTBUFF_SIZE);
|
|
|
|
outBuffOffset = 0;
|
|
|
|
}
|
|
|
|
else if( (outBuffOffset>0) && !g_Parallel)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "h5diff error: outBuffOffset>0, but we're not in parallel!\n");
|
|
|
|
}
|
2005-02-08 13:42:49 +08:00
|
|
|
}
|
|
|
|
|
[svn-r10170] Purpose:
Bug Fixes
Description:
Fixes for several bugs, including dumping of excess output to a temporary file, fix for printing
hsize_t datatype, and the long awaited fix for intermixed output.
Solution:
Fix 1: Overflow file
Previously, any output that a worker task made was buffered locally in memory, up to a point. Any
output beyond the size of the buffer (used to be 10k) was discarded. Now, the memory buffer size has been
changed to 1k and any output beyond this amount is sent a temporary file. This way, no output is lost
and memory usage is kept under control. The temporary file is deleted as soon as a worker task finishes
sending its contents to the manager.
Fix 2: hsize_t printing
Printing of the hsize_t datatype used to be handled by %Hu passed to HDfprintf. However, there is no corresponding HDvsnprintf that
is able to print hsize_t types. These are now printed with the aid of H5_PRINTF_LL_WIDTH.
Fix 3: Intermixed output fix
Intermixed output would occur on some machines (although I haven't seen it happen for a while) due to the unpredictability of the underlying network
and the speed at which various message would travel. This has been fixed by having all output send to the manager
for printing. The worker tasks no longer print the output themselves upon receipt of a token, but instead
send that data to the manager.
Platforms tested:
heping, eirene, tg-login (the only place that seems to still experience intermixed output every now and then)
Misc. update:
2005-03-10 02:38:36 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* Function: print_incoming_data
|
|
|
|
*
|
|
|
|
* Purpose: special function that prints any output that has been sent to the manager
|
2005-06-29 00:25:42 +08:00
|
|
|
* and is currently sitting in the incoming message queue
|
[svn-r10170] Purpose:
Bug Fixes
Description:
Fixes for several bugs, including dumping of excess output to a temporary file, fix for printing
hsize_t datatype, and the long awaited fix for intermixed output.
Solution:
Fix 1: Overflow file
Previously, any output that a worker task made was buffered locally in memory, up to a point. Any
output beyond the size of the buffer (used to be 10k) was discarded. Now, the memory buffer size has been
changed to 1k and any output beyond this amount is sent a temporary file. This way, no output is lost
and memory usage is kept under control. The temporary file is deleted as soon as a worker task finishes
sending its contents to the manager.
Fix 2: hsize_t printing
Printing of the hsize_t datatype used to be handled by %Hu passed to HDfprintf. However, there is no corresponding HDvsnprintf that
is able to print hsize_t types. These are now printed with the aid of H5_PRINTF_LL_WIDTH.
Fix 3: Intermixed output fix
Intermixed output would occur on some machines (although I haven't seen it happen for a while) due to the unpredictability of the underlying network
and the speed at which various message would travel. This has been fixed by having all output send to the manager
for printing. The worker tasks no longer print the output themselves upon receipt of a token, but instead
send that data to the manager.
Platforms tested:
heping, eirene, tg-login (the only place that seems to still experience intermixed output every now and then)
Misc. update:
2005-03-10 02:38:36 +08:00
|
|
|
*
|
|
|
|
* Return: none
|
|
|
|
*
|
|
|
|
* Programmer: Leon Arber
|
|
|
|
*
|
|
|
|
* Date: March 7, 2005
|
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void print_incoming_data(void)
|
|
|
|
{
|
2005-06-29 00:25:42 +08:00
|
|
|
char data[PRINT_DATA_MAX_SIZE+1];
|
|
|
|
int incomingMessage;
|
|
|
|
MPI_Status Status;
|
2005-06-29 03:20:56 +08:00
|
|
|
|
[svn-r10170] Purpose:
Bug Fixes
Description:
Fixes for several bugs, including dumping of excess output to a temporary file, fix for printing
hsize_t datatype, and the long awaited fix for intermixed output.
Solution:
Fix 1: Overflow file
Previously, any output that a worker task made was buffered locally in memory, up to a point. Any
output beyond the size of the buffer (used to be 10k) was discarded. Now, the memory buffer size has been
changed to 1k and any output beyond this amount is sent a temporary file. This way, no output is lost
and memory usage is kept under control. The temporary file is deleted as soon as a worker task finishes
sending its contents to the manager.
Fix 2: hsize_t printing
Printing of the hsize_t datatype used to be handled by %Hu passed to HDfprintf. However, there is no corresponding HDvsnprintf that
is able to print hsize_t types. These are now printed with the aid of H5_PRINTF_LL_WIDTH.
Fix 3: Intermixed output fix
Intermixed output would occur on some machines (although I haven't seen it happen for a while) due to the unpredictability of the underlying network
and the speed at which various message would travel. This has been fixed by having all output send to the manager
for printing. The worker tasks no longer print the output themselves upon receipt of a token, but instead
send that data to the manager.
Platforms tested:
heping, eirene, tg-login (the only place that seems to still experience intermixed output every now and then)
Misc. update:
2005-03-10 02:38:36 +08:00
|
|
|
do
|
2005-08-14 04:53:35 +08:00
|
|
|
{
|
2005-06-29 03:20:56 +08:00
|
|
|
MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD, &incomingMessage, &Status);
|
|
|
|
if(incomingMessage)
|
|
|
|
{
|
|
|
|
memset(data, 0, PRINT_DATA_MAX_SIZE+1);
|
|
|
|
MPI_Recv(data, PRINT_DATA_MAX_SIZE, MPI_CHAR, Status.MPI_SOURCE, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD, &Status);
|
|
|
|
|
|
|
|
printf("%s", data);
|
|
|
|
}
|
[svn-r10170] Purpose:
Bug Fixes
Description:
Fixes for several bugs, including dumping of excess output to a temporary file, fix for printing
hsize_t datatype, and the long awaited fix for intermixed output.
Solution:
Fix 1: Overflow file
Previously, any output that a worker task made was buffered locally in memory, up to a point. Any
output beyond the size of the buffer (used to be 10k) was discarded. Now, the memory buffer size has been
changed to 1k and any output beyond this amount is sent a temporary file. This way, no output is lost
and memory usage is kept under control. The temporary file is deleted as soon as a worker task finishes
sending its contents to the manager.
Fix 2: hsize_t printing
Printing of the hsize_t datatype used to be handled by %Hu passed to HDfprintf. However, there is no corresponding HDvsnprintf that
is able to print hsize_t types. These are now printed with the aid of H5_PRINTF_LL_WIDTH.
Fix 3: Intermixed output fix
Intermixed output would occur on some machines (although I haven't seen it happen for a while) due to the unpredictability of the underlying network
and the speed at which various message would travel. This has been fixed by having all output send to the manager
for printing. The worker tasks no longer print the output themselves upon receipt of a token, but instead
send that data to the manager.
Platforms tested:
heping, eirene, tg-login (the only place that seems to still experience intermixed output every now and then)
Misc. update:
2005-03-10 02:38:36 +08:00
|
|
|
} while(incomingMessage);
|
|
|
|
}
|
2005-02-10 02:19:54 +08:00
|
|
|
#endif
|
|
|
|
|
2002-10-10 00:33:05 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
2003-10-23 05:30:19 +08:00
|
|
|
* Function: h5diff
|
2002-10-10 00:33:05 +08:00
|
|
|
*
|
2004-07-21 03:21:03 +08:00
|
|
|
* Purpose: public function, can be called in an application program.
|
2003-10-23 05:30:19 +08:00
|
|
|
* return differences between 2 HDF5 files
|
2002-10-10 00:33:05 +08:00
|
|
|
*
|
2004-07-21 03:21:03 +08:00
|
|
|
* Return: Number of differences found.
|
2002-10-10 00:33:05 +08:00
|
|
|
*
|
|
|
|
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
|
|
|
|
*
|
2003-10-23 05:30:19 +08:00
|
|
|
* Date: October 22, 2003
|
2002-10-10 00:33:05 +08:00
|
|
|
*
|
2005-02-03 07:01:42 +08:00
|
|
|
* Modifications: Jan 2005 Leon Arber, larber@uiuc.edu
|
2005-06-29 00:25:42 +08:00
|
|
|
* Added support for parallel diffing
|
2005-02-03 07:01:42 +08:00
|
|
|
*
|
2002-10-10 00:33:05 +08:00
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
2005-01-27 07:03:29 +08:00
|
|
|
hsize_t
|
|
|
|
h5diff (const char *fname1,
|
2005-06-29 00:25:42 +08:00
|
|
|
const char *fname2,
|
|
|
|
const char *objname1, const char *objname2, diff_opt_t * options)
|
2002-10-10 00:33:05 +08:00
|
|
|
{
|
2005-04-19 05:21:35 +08:00
|
|
|
int nobjects1, nobjects2;
|
2005-01-27 07:03:29 +08:00
|
|
|
trav_info_t *info1 = NULL;
|
|
|
|
trav_info_t *info2 = NULL;
|
2005-08-14 04:53:35 +08:00
|
|
|
hid_t file1_id=(-1), file2_id=(-1);
|
2005-02-03 07:01:42 +08:00
|
|
|
char filenames[2][1024];
|
2005-01-27 07:03:29 +08:00
|
|
|
hsize_t nfound = 0;
|
2005-06-29 03:20:56 +08:00
|
|
|
int not_cmp = 0;
|
2005-08-14 04:53:35 +08:00
|
|
|
|
2005-02-03 07:01:42 +08:00
|
|
|
memset(filenames, 0, 1024*2);
|
2005-01-27 07:03:29 +08:00
|
|
|
|
|
|
|
|
2005-01-28 07:21:05 +08:00
|
|
|
if (options->m_quiet && (options->m_verbose || options->m_report))
|
|
|
|
{
|
|
|
|
printf
|
2005-06-29 00:25:42 +08:00
|
|
|
("Error: -q (quiet mode) cannot be added to verbose or report modes\n");
|
2005-01-28 07:21:05 +08:00
|
|
|
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)
|
|
|
|
{
|
2005-06-29 00:25:42 +08:00
|
|
|
printf ("h5diff: <%s>: unable to open file\n", fname1);
|
|
|
|
options->err_stat = 1;
|
2005-01-28 07:21:05 +08:00
|
|
|
|
2005-02-03 07:01:42 +08:00
|
|
|
#ifdef H5_HAVE_PARALLEL
|
2005-06-29 00:25:42 +08:00
|
|
|
if(g_Parallel)
|
|
|
|
{
|
|
|
|
/* Let tasks know that they won't be needed */
|
|
|
|
phdiff_dismiss_workers();
|
|
|
|
}
|
2005-01-27 07:03:29 +08:00
|
|
|
#endif
|
|
|
|
|
2005-06-29 00:25:42 +08:00
|
|
|
goto out;
|
2005-01-27 07:03:29 +08:00
|
|
|
}
|
|
|
|
if ((file2_id = H5Fopen (fname2, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
|
|
|
|
{
|
2005-06-29 00:25:42 +08:00
|
|
|
printf ("h5diff: <%s>: unable to open file\n", fname2);
|
|
|
|
options->err_stat = 1;
|
2005-01-27 07:03:29 +08:00
|
|
|
|
2005-02-03 07:01:42 +08:00
|
|
|
#ifdef H5_HAVE_PARALLEL
|
2005-06-29 00:25:42 +08:00
|
|
|
if(g_Parallel)
|
|
|
|
{
|
|
|
|
/* Let tasks know that they won't be needed */
|
|
|
|
phdiff_dismiss_workers();
|
|
|
|
}
|
2005-01-27 07:03:29 +08:00
|
|
|
#endif
|
|
|
|
|
2005-06-29 00:25:42 +08:00
|
|
|
goto out;
|
2005-01-27 07:03:29 +08:00
|
|
|
}
|
|
|
|
/* enable error reporting */
|
|
|
|
}
|
|
|
|
H5E_END_TRY;
|
2004-07-21 03:21:03 +08:00
|
|
|
|
2003-10-23 05:30:19 +08:00
|
|
|
|
2003-01-24 06:08:51 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* get the number of objects in the files
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2005-01-27 07:03:29 +08:00
|
|
|
nobjects1 = h5trav_getinfo (file1_id, NULL, 0);
|
|
|
|
nobjects2 = h5trav_getinfo (file2_id, NULL, 0);
|
2003-01-24 06:08:51 +08:00
|
|
|
|
2005-01-27 07:03:29 +08:00
|
|
|
if (nobjects1 < 0 || nobjects2 < 0)
|
|
|
|
{
|
|
|
|
printf ("Error: Could not get get file contents\n");
|
|
|
|
options->err_stat = 1;
|
2005-02-08 13:42:49 +08:00
|
|
|
#ifdef H5_HAVE_PARALLEL
|
2005-06-29 00:25:42 +08:00
|
|
|
if(g_Parallel)
|
|
|
|
{
|
|
|
|
/* Let tasks know that they won't be needed */
|
|
|
|
phdiff_dismiss_workers();
|
|
|
|
}
|
2005-02-08 13:42:49 +08:00
|
|
|
#endif
|
2005-01-27 07:03:29 +08:00
|
|
|
goto out;
|
|
|
|
}
|
2004-07-21 03:21:03 +08:00
|
|
|
|
2005-01-27 07:03:29 +08:00
|
|
|
assert (nobjects1 > 0);
|
|
|
|
assert (nobjects2 > 0);
|
2004-07-21 03:21:03 +08:00
|
|
|
|
2003-01-24 06:08:51 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* get the list of objects in the files
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
2005-01-27 07:03:29 +08:00
|
|
|
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)
|
2005-06-29 00:25:42 +08:00
|
|
|
h5trav_freeinfo (info1, nobjects1);
|
2005-01-27 07:03:29 +08:00
|
|
|
if (info2)
|
2005-06-29 00:25:42 +08:00
|
|
|
h5trav_freeinfo (info2, nobjects1);
|
2005-02-08 13:42:49 +08:00
|
|
|
#ifdef H5_HAVE_PARALLEL
|
2005-06-29 00:25:42 +08:00
|
|
|
if(g_Parallel)
|
|
|
|
{
|
|
|
|
/* Let tasks know that they won't be needed */
|
|
|
|
phdiff_dismiss_workers();
|
|
|
|
}
|
2005-02-08 13:42:49 +08:00
|
|
|
#endif
|
2005-01-27 07:03:29 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
h5trav_getinfo (file1_id, info1, 0);
|
|
|
|
h5trav_getinfo (file2_id, info2, 0);
|
2003-01-25 02:01:44 +08:00
|
|
|
|
2003-01-24 06:08:51 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* object name was supplied
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2005-08-14 04:53:35 +08:00
|
|
|
|
2005-01-27 07:03:29 +08:00
|
|
|
if (objname1)
|
|
|
|
{
|
2005-08-14 04:53:35 +08:00
|
|
|
|
2005-02-03 07:01:42 +08:00
|
|
|
#ifdef H5_HAVE_PARALLEL
|
2005-06-29 00:25:42 +08:00
|
|
|
if(g_Parallel)
|
|
|
|
{
|
|
|
|
/* Let tasks know that they won't be needed */
|
|
|
|
phdiff_dismiss_workers();
|
|
|
|
}
|
2005-01-27 07:03:29 +08:00
|
|
|
#endif
|
|
|
|
assert (objname2);
|
2005-06-29 00:25:42 +08:00
|
|
|
options->cmn_objs = 1; /* eliminate warning */
|
2005-01-27 07:03:29 +08:00
|
|
|
nfound = diff_compare (file1_id, fname1, objname1, nobjects1, info1,
|
2005-06-29 00:25:42 +08:00
|
|
|
file2_id, fname2, objname2, nobjects2, info2,
|
|
|
|
options);
|
2005-01-27 07:03:29 +08:00
|
|
|
}
|
2003-03-06 09:26:25 +08:00
|
|
|
|
2003-01-24 06:08:51 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
2003-03-26 22:23:48 +08:00
|
|
|
* compare all
|
2003-01-24 06:08:51 +08:00
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2003-02-25 02:53:22 +08:00
|
|
|
|
2005-01-27 07:03:29 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
|
2005-02-03 07:01:42 +08:00
|
|
|
#ifdef H5_HAVE_PARALLEL
|
|
|
|
if(g_Parallel)
|
|
|
|
{
|
2005-04-19 05:21:35 +08:00
|
|
|
int i;
|
|
|
|
|
2005-06-29 00:25:42 +08:00
|
|
|
if( (strlen(fname1) > 1024) || (strlen(fname2) > 1024))
|
|
|
|
{
|
2005-06-29 03:20:56 +08:00
|
|
|
fprintf(stderr, "The parallel diff only supports path names up to 1024 characters\n");
|
2005-06-29 00:25:42 +08:00
|
|
|
MPI_Abort(MPI_COMM_WORLD, 0);
|
|
|
|
}
|
2005-02-03 07:01:42 +08:00
|
|
|
|
2005-06-29 00:25:42 +08:00
|
|
|
strcpy(filenames[0], fname1);
|
|
|
|
strcpy(filenames[1], fname2);
|
2005-01-27 07:03:29 +08:00
|
|
|
|
2005-06-29 00:25:42 +08:00
|
|
|
/* Alert the worker tasks that there's going to be work. */
|
2005-02-03 07:01:42 +08:00
|
|
|
|
2005-06-29 00:25:42 +08:00
|
|
|
for(i=1; i<g_nTasks; i++)
|
|
|
|
MPI_Send(filenames, 1024*2, MPI_CHAR, i, MPI_TAG_PARALLEL, MPI_COMM_WORLD);
|
2005-02-03 07:01:42 +08:00
|
|
|
}
|
2005-01-27 07:03:29 +08:00
|
|
|
#endif
|
2005-02-03 07:01:42 +08:00
|
|
|
nfound = diff_match (file1_id, nobjects1, info1,
|
2005-06-29 00:25:42 +08:00
|
|
|
file2_id, nobjects2, info2, options);
|
2005-06-29 03:20:56 +08:00
|
|
|
|
2005-01-27 07:03:29 +08:00
|
|
|
}
|
2003-10-31 05:51:32 +08:00
|
|
|
|
|
|
|
|
2005-01-27 07:03:29 +08:00
|
|
|
h5trav_freeinfo (info1, nobjects1);
|
|
|
|
h5trav_freeinfo (info2, nobjects2);
|
2003-10-31 05:51:32 +08:00
|
|
|
|
2005-01-27 07:03:29 +08:00
|
|
|
out:
|
|
|
|
/* close */
|
|
|
|
H5E_BEGIN_TRY
|
|
|
|
{
|
|
|
|
H5Fclose (file1_id);
|
|
|
|
H5Fclose (file2_id);
|
|
|
|
}
|
|
|
|
H5E_END_TRY;
|
|
|
|
|
|
|
|
return nfound;
|
2003-03-26 22:23:48 +08:00
|
|
|
}
|
2003-05-19 13:09:08 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
2005-02-03 07:01:42 +08:00
|
|
|
* Function: diff_match
|
2003-05-19 13:09:08 +08:00
|
|
|
*
|
2005-08-14 04:53:35 +08:00
|
|
|
* Purpose: Find common objects; the algorithm used for this search is the
|
|
|
|
* cosequential match algorithm and is described in
|
2003-05-19 13:09:08 +08:00
|
|
|
* Folk, Michael; Zoellick, Bill. (1992). File Structures. Addison-Wesley.
|
|
|
|
*
|
2003-05-20 00:14:26 +08:00
|
|
|
* Return: Number of differences found
|
2003-05-19 13:09:08 +08:00
|
|
|
*
|
|
|
|
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
|
|
|
|
*
|
|
|
|
* Date: May 9, 2003
|
2005-08-14 04:53:35 +08:00
|
|
|
*
|
2005-02-03 07:01:42 +08:00
|
|
|
* Modifications: Jan 2005 Leon Arber, larber@uiuc.edu
|
2005-06-29 00:25:42 +08:00
|
|
|
* Added support for parallel diffing
|
2003-05-19 13:09:08 +08:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2005-01-27 07:03:29 +08:00
|
|
|
hsize_t
|
2005-02-03 07:01:42 +08:00
|
|
|
diff_match (hid_t file1_id,
|
2005-06-29 00:25:42 +08:00
|
|
|
int nobjects1,
|
|
|
|
trav_info_t * info1,
|
|
|
|
hid_t file2_id,
|
|
|
|
int nobjects2, trav_info_t * info2, diff_opt_t * options)
|
2003-05-19 13:09:08 +08:00
|
|
|
{
|
2005-01-27 07:03:29 +08:00
|
|
|
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)
|
|
|
|
{
|
2005-06-29 00:25:42 +08:00
|
|
|
/* 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 */
|
2005-01-27 07:03:29 +08:00
|
|
|
|
|
|
|
/* list1 did not end */
|
|
|
|
if (curr1 < nobjects1)
|
|
|
|
{
|
2005-06-29 00:25:42 +08:00
|
|
|
while (curr1 < nobjects1)
|
|
|
|
{
|
|
|
|
infile[0] = 1;
|
|
|
|
infile[1] = 0;
|
|
|
|
trav_table_addflags (infile, info1[curr1].name, info1[curr1].type,
|
|
|
|
table);
|
|
|
|
curr1++;
|
|
|
|
}
|
2005-01-27 07:03:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* list2 did not end */
|
|
|
|
if (curr2 < nobjects2)
|
|
|
|
{
|
2005-06-29 00:25:42 +08:00
|
|
|
while (curr2 < nobjects2)
|
|
|
|
{
|
|
|
|
infile[0] = 0;
|
|
|
|
infile[1] = 1;
|
|
|
|
trav_table_addflags (infile, info2[curr2].name, info2[curr2].type,
|
|
|
|
table);
|
|
|
|
curr2++;
|
|
|
|
}
|
2005-01-27 07:03:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* print the list
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (options->m_verbose)
|
|
|
|
{
|
2005-06-29 00:25:42 +08:00
|
|
|
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");
|
2005-01-27 07:03:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* do the diff for common objects
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
{
|
2005-02-03 07:01:42 +08:00
|
|
|
#ifdef H5_HAVE_PARALLEL
|
2005-08-19 03:37:32 +08:00
|
|
|
char* workerTasks = malloc((g_nTasks-1) * sizeof(char));
|
|
|
|
int n;
|
|
|
|
int busyTasks=0;
|
|
|
|
struct diffs_found nFoundbyWorker;
|
|
|
|
struct diff_args args;
|
|
|
|
int havePrintToken = 1;
|
|
|
|
MPI_Status Status;
|
|
|
|
|
|
|
|
/*set all tasks as free */
|
|
|
|
memset(workerTasks, 1, g_nTasks-1);
|
2005-01-27 07:03:29 +08:00
|
|
|
#endif
|
|
|
|
|
2005-06-29 00:25:42 +08:00
|
|
|
for (i = 0; i < table->nobjs; i++)
|
|
|
|
{
|
|
|
|
if (table->objs[i].flags[0] && table->objs[i].flags[1])
|
|
|
|
{
|
2005-05-08 03:37:48 +08:00
|
|
|
#ifdef H5_HAVE_PARALLEL
|
2005-06-29 00:25:42 +08:00
|
|
|
int workerFound = 0;
|
2005-05-08 03:37:48 +08:00
|
|
|
#endif /* H5_HAVE_PARALLEL */
|
2005-06-29 00:25:42 +08:00
|
|
|
options->cmn_objs = 1;
|
|
|
|
if(!g_Parallel)
|
|
|
|
{
|
|
|
|
nfound += diff (file1_id,
|
|
|
|
table->objs[i].name,
|
|
|
|
file2_id,
|
|
|
|
table->objs[i].name, options, table->objs[i].type);
|
|
|
|
}
|
2005-02-03 07:01:42 +08:00
|
|
|
#ifdef H5_HAVE_PARALLEL
|
2005-06-29 00:25:42 +08:00
|
|
|
else
|
|
|
|
{
|
2005-08-19 03:37:32 +08:00
|
|
|
h5diffdebug("beginning of big else block\n");
|
2005-06-29 00:25:42 +08:00
|
|
|
/* We're in parallel mode */
|
|
|
|
/* Since the data type of diff value is hsize_t which can
|
|
|
|
* be arbitary large such that there is no MPI type that
|
|
|
|
* matches it, the value is passed between processes as
|
|
|
|
* an array of bytes in order to be portable. But this
|
|
|
|
* may not work in non-homogeneous MPI environments.
|
|
|
|
*/
|
|
|
|
|
2005-08-14 04:53:35 +08:00
|
|
|
/*Set up args to pass to worker task. */
|
2005-06-29 00:25:42 +08:00
|
|
|
if(strlen(table->objs[i].name) > 255)
|
|
|
|
{
|
2005-08-19 03:37:32 +08:00
|
|
|
printf("The parallel diff only supports object names up to 255 characters\n");
|
|
|
|
MPI_Abort(MPI_COMM_WORLD, 0);
|
2005-06-29 00:25:42 +08:00
|
|
|
}
|
2005-08-14 04:53:35 +08:00
|
|
|
|
2005-06-29 00:25:42 +08:00
|
|
|
strcpy(args.name, table->objs[i].name);
|
|
|
|
args.options = *options;
|
|
|
|
args.type= table->objs[i].type;
|
|
|
|
|
2005-08-19 03:37:32 +08:00
|
|
|
h5diffdebug2("busyTasks=%d\n", busyTasks);
|
2005-06-29 00:25:42 +08:00
|
|
|
/* if there are any outstanding print requests, let's handle one. */
|
|
|
|
if(busyTasks > 0)
|
|
|
|
{
|
2005-08-18 03:21:36 +08:00
|
|
|
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);
|
|
|
|
|
2005-08-19 03:37:32 +08:00
|
|
|
/* first block*/
|
2005-08-18 03:21:36 +08:00
|
|
|
if(incomingMessage)
|
|
|
|
{
|
|
|
|
workerTasks[Status.MPI_SOURCE-1] = 1;
|
|
|
|
MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status);
|
|
|
|
nfound += nFoundbyWorker.nfound;
|
|
|
|
options->not_cmp = options->not_cmp | nFoundbyWorker.not_cmp;
|
|
|
|
busyTasks--;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check to see if the print token was returned. */
|
|
|
|
if(!havePrintToken)
|
|
|
|
{
|
|
|
|
/* If we don't have the token, someone is probably sending us output */
|
|
|
|
print_incoming_data();
|
|
|
|
|
|
|
|
/* 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, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
|
|
|
|
nfound += nFoundbyWorker.nfound;
|
|
|
|
options->not_cmp = options->not_cmp | nFoundbyWorker.not_cmp;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2005-06-29 00:25:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* check array of tasks to see which ones are free.
|
2005-08-14 04:53:35 +08:00
|
|
|
* Manager task never does work, so freeTasks[0] is really
|
2005-06-29 00:25:42 +08:00
|
|
|
* worker task 0. */
|
|
|
|
|
|
|
|
for(n=1; (n<g_nTasks) && !workerFound; n++)
|
|
|
|
{
|
2005-08-19 03:37:32 +08:00
|
|
|
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);
|
2005-06-29 00:25:42 +08:00
|
|
|
|
2005-08-19 03:37:32 +08:00
|
|
|
/* increment counter for total number of prints. */
|
|
|
|
busyTasks++;
|
2005-06-29 00:25:42 +08:00
|
|
|
|
2005-08-19 03:37:32 +08:00
|
|
|
/* mark worker as busy */
|
|
|
|
workerTasks[n-1] = 0;
|
|
|
|
workerFound = 1;
|
|
|
|
}
|
2005-06-29 00:25:42 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-08-19 03:37:32 +08:00
|
|
|
h5diffdebug2("workerfound is %d \n", workerFound);
|
2005-06-29 00:25:42 +08:00
|
|
|
if(!workerFound)
|
|
|
|
{
|
2005-08-18 03:21:36 +08:00
|
|
|
/* 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)
|
|
|
|
{
|
|
|
|
while(!havePrintToken) {
|
|
|
|
int incomingMessage;
|
|
|
|
print_incoming_data();
|
|
|
|
MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &incomingMessage, &Status);
|
|
|
|
if(incomingMessage)
|
|
|
|
{
|
|
|
|
MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
|
|
|
|
havePrintToken = 1;
|
|
|
|
nfound += nFoundbyWorker.nfound;
|
|
|
|
options->not_cmp = options->not_cmp | nFoundbyWorker.not_cmp;
|
|
|
|
/* send this task the work unit. */
|
|
|
|
MPI_Send(&args, sizeof(struct diff_args), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_ARGS, MPI_COMM_WORLD);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-06-29 00:25:42 +08:00
|
|
|
/* if we do have the token, check for task to free up, or wait for a task to request it */
|
2005-08-18 03:21:36 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* But first print all the data in our incoming queue */
|
|
|
|
print_incoming_data();
|
|
|
|
MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
|
|
|
|
if(Status.MPI_TAG == MPI_TAG_DONE)
|
|
|
|
{
|
|
|
|
MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status);
|
|
|
|
nfound += nFoundbyWorker.nfound;
|
|
|
|
options->not_cmp = options->not_cmp | nFoundbyWorker.not_cmp;
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
int 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);
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &incomingMessage, &Status);
|
|
|
|
|
|
|
|
print_incoming_data();
|
|
|
|
}
|
|
|
|
while(!incomingMessage);
|
|
|
|
|
|
|
|
|
|
|
|
MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
|
|
|
|
nfound += nFoundbyWorker.nfound;
|
|
|
|
options->not_cmp = options->not_cmp | nFoundbyWorker.not_cmp;
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
2005-06-29 00:25:42 +08:00
|
|
|
}
|
|
|
|
}
|
2005-08-19 03:37:32 +08:00
|
|
|
#endif /* H5_HAVE_PARALLEL */
|
2005-06-29 00:25:42 +08:00
|
|
|
}
|
|
|
|
}
|
2005-08-19 03:37:32 +08:00
|
|
|
h5diffdebug("done with for loop\n");
|
2005-01-27 07:03:29 +08:00
|
|
|
|
2005-02-03 07:01:42 +08:00
|
|
|
#ifdef H5_HAVE_PARALLEL
|
2005-06-29 00:25:42 +08:00
|
|
|
if(g_Parallel)
|
|
|
|
{
|
|
|
|
while(busyTasks > 0) /* make sure all tasks are done */
|
|
|
|
{
|
2005-08-19 03:37:32 +08:00
|
|
|
MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
|
|
|
|
if(Status.MPI_TAG == MPI_TAG_DONE)
|
|
|
|
{
|
|
|
|
MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status);
|
|
|
|
nfound += nFoundbyWorker.nfound;
|
|
|
|
options->not_cmp = options->not_cmp | nFoundbyWorker.not_cmp;
|
|
|
|
busyTasks--;
|
|
|
|
}
|
|
|
|
else if(Status.MPI_TAG == MPI_TAG_TOK_RETURN)
|
|
|
|
{
|
|
|
|
MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_DONE, MPI_COMM_WORLD, &Status);
|
|
|
|
nfound += nFoundbyWorker.nfound;
|
|
|
|
options->not_cmp = options->not_cmp | nFoundbyWorker.not_cmp;
|
|
|
|
busyTasks--;
|
|
|
|
havePrintToken = 1;
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
int incomingMessage;
|
|
|
|
MPI_Send(NULL, 0, MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD);
|
|
|
|
do
|
|
|
|
{
|
|
|
|
MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &incomingMessage, &Status);
|
|
|
|
|
|
|
|
print_incoming_data();
|
|
|
|
}
|
|
|
|
while(!incomingMessage);
|
|
|
|
MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
|
|
|
|
nfound += nFoundbyWorker.nfound;
|
|
|
|
options->not_cmp = options->not_cmp | nFoundbyWorker.not_cmp;
|
|
|
|
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;
|
|
|
|
int incomingMessage;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
MPI_Iprobe(MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &incomingMessage, &Status);
|
|
|
|
|
|
|
|
print_incoming_data();
|
|
|
|
}
|
|
|
|
while(!incomingMessage);
|
|
|
|
|
|
|
|
|
|
|
|
MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, MPI_ANY_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
|
|
|
|
nfound += nFoundbyWorker.nfound;
|
|
|
|
options->not_cmp = options->not_cmp | nFoundbyWorker.not_cmp;
|
|
|
|
busyTasks--;
|
|
|
|
MPI_Send(NULL, 0, MPI_BYTE, source, MPI_TAG_PRINT_TOK, MPI_COMM_WORLD);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(Status.MPI_TAG == MPI_TAG_TOK_RETURN)
|
|
|
|
{
|
|
|
|
MPI_Recv(&nFoundbyWorker, sizeof(nFoundbyWorker), MPI_BYTE, Status.MPI_SOURCE, MPI_TAG_TOK_RETURN, MPI_COMM_WORLD, &Status);
|
|
|
|
nfound += nFoundbyWorker.nfound;
|
|
|
|
options->not_cmp = options->not_cmp | nFoundbyWorker.not_cmp;
|
|
|
|
busyTasks--;
|
|
|
|
havePrintToken = 1;
|
|
|
|
}
|
|
|
|
else if(Status.MPI_TAG == MPI_TAG_PRINT_DATA)
|
|
|
|
{
|
|
|
|
char data[PRINT_DATA_MAX_SIZE+1];
|
|
|
|
memset(data, 0, PRINT_DATA_MAX_SIZE+1);
|
|
|
|
|
|
|
|
MPI_Recv(data, PRINT_DATA_MAX_SIZE, MPI_CHAR, Status.MPI_SOURCE, MPI_TAG_PRINT_DATA, MPI_COMM_WORLD, &Status);
|
|
|
|
|
|
|
|
printf("%s", data);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf("ph5diff-manager: ERROR!! Invalid tag (%d) received \n", Status.MPI_TAG);
|
|
|
|
MPI_Abort(MPI_COMM_WORLD, 0);
|
|
|
|
}
|
2005-06-29 00:25:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for(i=1; i<g_nTasks; i++)
|
2005-08-19 03:37:32 +08:00
|
|
|
MPI_Send(NULL, 0, MPI_BYTE, i, MPI_TAG_END, MPI_COMM_WORLD);
|
2005-06-29 00:25:42 +08:00
|
|
|
|
|
|
|
/* Print any final data waiting in our queue */
|
|
|
|
print_incoming_data();
|
|
|
|
|
|
|
|
}
|
2005-08-19 03:37:32 +08:00
|
|
|
h5diffdebug("done with if block\n");
|
2005-06-29 00:25:42 +08:00
|
|
|
|
|
|
|
free(workerTasks);
|
2005-08-19 03:37:32 +08:00
|
|
|
#endif /* H5_HAVE_PARALLEL */
|
2005-01-27 07:03:29 +08:00
|
|
|
}
|
|
|
|
/* free table */
|
|
|
|
trav_table_free (table);
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* do the diff for the root.
|
2005-08-14 04:53:35 +08:00
|
|
|
* this is a special case, we get an ID for the root group and call diff()
|
2005-01-27 07:03:29 +08:00
|
|
|
* 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;
|
2003-05-19 13:09:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-03-26 22:23:48 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
2003-10-29 01:40:05 +08:00
|
|
|
* Function: diff_compare
|
2003-03-26 22:23:48 +08:00
|
|
|
*
|
2003-10-29 01:40:05 +08:00
|
|
|
* Purpose: get objects from list, and check for the same type
|
2003-03-26 22:23:48 +08:00
|
|
|
*
|
2003-05-20 00:14:26 +08:00
|
|
|
* Return: Number of differences found
|
2003-03-26 22:23:48 +08:00
|
|
|
*
|
|
|
|
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
|
|
|
|
*
|
2003-05-11 03:38:57 +08:00
|
|
|
* Date: May 9, 2003
|
2003-03-26 22:23:48 +08:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
2005-01-27 07:03:29 +08:00
|
|
|
hsize_t
|
|
|
|
diff_compare (hid_t file1_id,
|
2005-06-29 00:25:42 +08:00
|
|
|
const char *file1_name,
|
|
|
|
const char *obj1_name,
|
|
|
|
int nobjects1,
|
|
|
|
trav_info_t * info1,
|
|
|
|
hid_t file2_id,
|
|
|
|
const char *file2_name,
|
|
|
|
const char *obj2_name,
|
|
|
|
int nobjects2, trav_info_t * info2, diff_opt_t * options)
|
2003-03-26 22:23:48 +08:00
|
|
|
{
|
|
|
|
|
2005-01-27 07:03:29 +08:00
|
|
|
int f1 = 0, f2 = 0;
|
|
|
|
hsize_t nfound = 0;
|
|
|
|
|
|
|
|
int i = h5trav_getindex (obj1_name, nobjects1, info1);
|
|
|
|
int j = h5trav_getindex (obj2_name, nobjects2, info2);
|
|
|
|
|
|
|
|
if (i == -1)
|
|
|
|
{
|
2005-06-29 00:25:42 +08:00
|
|
|
parallel_print ("Object <%s> could not be found in <%s>\n", obj1_name,
|
|
|
|
file1_name);
|
|
|
|
f1 = 1;
|
2005-01-27 07:03:29 +08:00
|
|
|
}
|
2005-06-29 00:25:42 +08:00
|
|
|
if (j == -1)
|
|
|
|
{
|
|
|
|
parallel_print ("Object <%s> could not be found in <%s>\n", obj2_name,
|
|
|
|
file2_name);
|
|
|
|
f2 = 1;
|
|
|
|
}
|
|
|
|
if (f1 || f2)
|
|
|
|
{
|
|
|
|
options->err_stat = 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* use the name with "/" first, as obtained by iterator function */
|
|
|
|
obj1_name = info1[i].name;
|
2005-01-27 07:03:29 +08:00
|
|
|
obj2_name = info2[j].name;
|
|
|
|
|
|
|
|
/* objects are not the same type */
|
|
|
|
if (info1[i].type != info2[j].type)
|
|
|
|
{
|
|
|
|
if (options->m_verbose)
|
2005-06-29 00:25:42 +08:00
|
|
|
parallel_print
|
|
|
|
("Comparison not possible: <%s> is of type %s and <%s> is of type %s\n",
|
|
|
|
obj1_name, get_type (info1[i].type), obj2_name,
|
|
|
|
get_type (info2[j].type));
|
|
|
|
options->not_cmp=1;
|
2005-01-27 07:03:29 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
nfound =
|
|
|
|
diff (file1_id, obj1_name, file2_id, obj2_name, options, info1[i].type);
|
|
|
|
|
|
|
|
return nfound;
|
2003-03-26 22:23:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* Function: diff
|
|
|
|
*
|
2003-05-11 03:38:57 +08:00
|
|
|
* Purpose: switch between types and choose the diff function
|
2003-12-03 07:13:27 +08:00
|
|
|
* TYPE is either
|
2005-08-14 04:53:35 +08:00
|
|
|
* H5G_LINK Object is a symbolic link
|
|
|
|
* H5G_GROUP Object is a group
|
|
|
|
* H5G_DATASET Object is a dataset
|
|
|
|
* H5G_TYPE Object is a named data type
|
2003-03-26 22:23:48 +08:00
|
|
|
*
|
2003-05-20 00:14:26 +08:00
|
|
|
* Return: Number of differences found
|
2003-03-26 22:23:48 +08:00
|
|
|
*
|
|
|
|
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
|
|
|
|
*
|
2003-05-11 03:38:57 +08:00
|
|
|
* Date: May 9, 2003
|
2003-03-26 22:23:48 +08:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
2005-01-27 07:03:29 +08:00
|
|
|
hsize_t
|
|
|
|
diff (hid_t file1_id,
|
|
|
|
const char *path1,
|
|
|
|
hid_t file2_id, const char *path2, diff_opt_t * options, H5G_obj_t type)
|
2003-03-26 22:23:48 +08:00
|
|
|
{
|
2005-02-08 13:42:49 +08:00
|
|
|
hid_t type1_id=(-1);
|
|
|
|
hid_t type2_id=(-1);
|
|
|
|
hid_t grp1_id=(-1);
|
|
|
|
hid_t grp2_id=(-1);
|
|
|
|
int ret;
|
|
|
|
H5G_stat_t sb1;
|
|
|
|
H5G_stat_t sb2;
|
|
|
|
char *buf1 = NULL;
|
|
|
|
char *buf2 = NULL;
|
|
|
|
hsize_t nfound = 0;
|
2005-01-27 07:03:29 +08:00
|
|
|
|
2005-02-08 13:42:49 +08:00
|
|
|
switch (type)
|
2005-01-27 07:03:29 +08:00
|
|
|
{
|
2005-06-29 00:25:42 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* H5G_DATASET
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2005-07-01 04:57:01 +08:00
|
|
|
case H5G_DATASET:
|
2005-06-29 00:25:42 +08:00
|
|
|
|
2005-07-01 04:57:01 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* verbose, always print name
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2005-06-29 00:25:42 +08:00
|
|
|
if (options->m_verbose)
|
|
|
|
{
|
2005-07-01 04:57:01 +08:00
|
|
|
if (print_objname (options, (hsize_t)1))
|
2005-08-14 04:53:35 +08:00
|
|
|
parallel_print("Dataset: <%s> and <%s>\n", path1, path2);
|
2005-07-01 04:57:01 +08:00
|
|
|
nfound = diff_dataset (file1_id, file2_id, path1, path2, options);
|
|
|
|
/* always print the number of differences found */
|
2005-08-14 04:53:35 +08:00
|
|
|
print_found(nfound);
|
2005-06-29 00:25:42 +08:00
|
|
|
}
|
2005-07-01 04:57:01 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* non verbose, check first if we have differences
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2005-06-29 00:25:42 +08:00
|
|
|
else
|
|
|
|
{
|
2005-07-01 04:57:01 +08:00
|
|
|
if (options->m_quiet == 0)
|
2005-06-29 00:25:42 +08:00
|
|
|
{
|
2005-07-01 04:57:01 +08:00
|
|
|
/* shut up temporarily */
|
|
|
|
options->m_quiet = 1;
|
|
|
|
nfound = diff_dataset (file1_id, file2_id, path1, path2, options);
|
|
|
|
/* print again */
|
|
|
|
options->m_quiet = 0;
|
|
|
|
if (nfound)
|
|
|
|
{
|
|
|
|
if (print_objname (options, nfound))
|
|
|
|
parallel_print("Dataset: <%s> and <%s>\n", path1, path2);
|
|
|
|
nfound = diff_dataset (file1_id, file2_id, path1, path2, options);
|
2005-08-14 04:53:35 +08:00
|
|
|
/* print the number of differences found only when found
|
2005-07-01 04:57:01 +08:00
|
|
|
this is valid for the default mode and report mode */
|
2005-08-14 04:53:35 +08:00
|
|
|
print_found(nfound);
|
2005-07-01 04:57:01 +08:00
|
|
|
} /*if nfound */
|
|
|
|
} /*if quiet */
|
2005-06-29 00:25:42 +08:00
|
|
|
|
2005-07-01 04:57:01 +08:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* quiet mode, just count differences
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nfound = diff_dataset (file1_id, file2_id, path1, path2, options);
|
|
|
|
}
|
|
|
|
} /*else verbose */
|
2005-08-14 04:53:35 +08:00
|
|
|
|
2005-06-29 00:25:42 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* H5G_TYPE
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
case H5G_TYPE:
|
|
|
|
if ((type1_id = H5Topen (file1_id, path1)) < 0)
|
|
|
|
goto out;
|
|
|
|
if ((type2_id = H5Topen (file2_id, path2)) < 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
if ((ret = H5Tequal (type1_id, type2_id)) < 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
/* if H5Tequal is > 0 then the datatypes refer to the same datatype */
|
|
|
|
nfound = (ret > 0) ? 0 : 1;
|
|
|
|
|
|
|
|
if (print_objname (options, nfound))
|
2005-07-01 04:57:01 +08:00
|
|
|
parallel_print("Datatype: <%s> and <%s>\n", path1, path2);
|
|
|
|
|
|
|
|
/* always print the number of differences found in verbose mode */
|
|
|
|
if (options->m_verbose)
|
|
|
|
print_found(nfound);
|
2005-06-29 00:25:42 +08:00
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* compare attributes
|
|
|
|
* the if condition refers to cases when the dataset is a referenced object
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
if (path1)
|
2005-08-14 04:53:35 +08:00
|
|
|
diff_attr (type1_id, type2_id, path1, path2, options);
|
2005-06-29 00:25:42 +08:00
|
|
|
|
|
|
|
if (H5Tclose (type1_id) < 0)
|
|
|
|
goto out;
|
|
|
|
if (H5Tclose (type2_id) < 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* H5G_GROUP
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
case H5G_GROUP:
|
|
|
|
if ((grp1_id = H5Gopen (file1_id, path1)) < 0)
|
|
|
|
goto out;
|
|
|
|
if ((grp2_id = H5Gopen (file2_id, path2)) < 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
ret = HDstrcmp (path1, path2);
|
|
|
|
|
|
|
|
/* if "path1" != "path2" then the groups are "different" */
|
|
|
|
nfound = (ret != 0) ? 1 : 0;
|
|
|
|
|
|
|
|
if (print_objname (options, nfound))
|
2005-07-01 04:57:01 +08:00
|
|
|
parallel_print("Group: <%s> and <%s>\n", path1, path2);
|
|
|
|
|
|
|
|
/* always print the number of differences found in verbose mode */
|
|
|
|
if (options->m_verbose)
|
|
|
|
print_found(nfound);
|
2005-06-29 00:25:42 +08:00
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* compare attributes
|
|
|
|
* the if condition refers to cases when the dataset is a referenced object
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
if (path1)
|
|
|
|
diff_attr (grp1_id, grp2_id, path1, path2, options);
|
|
|
|
|
|
|
|
if (H5Gclose (grp1_id) < 0)
|
|
|
|
goto out;
|
|
|
|
if (H5Gclose (grp2_id) < 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
* H5G_LINK
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
case H5G_LINK:
|
|
|
|
if (H5Gget_objinfo (file1_id, path1, FALSE, &sb1) < 0)
|
|
|
|
goto out;
|
|
|
|
if (H5Gget_objinfo (file1_id, path1, FALSE, &sb2) < 0)
|
|
|
|
goto out;
|
|
|
|
|
2005-08-27 21:34:28 +08:00
|
|
|
buf1 = malloc (sb1.u.slink.linklen);
|
|
|
|
buf2 = malloc (sb2.u.slink.linklen);
|
2005-06-29 00:25:42 +08:00
|
|
|
|
2005-08-27 21:34:28 +08:00
|
|
|
if (H5Gget_linkval (file1_id, path1, sb1.u.slink.linklen, buf1) < 0)
|
2005-06-29 00:25:42 +08:00
|
|
|
goto out;
|
2005-08-27 21:34:28 +08:00
|
|
|
if (H5Gget_linkval (file2_id, path2, sb1.u.slink.linklen, buf2) < 0)
|
2005-06-29 00:25:42 +08:00
|
|
|
goto out;
|
|
|
|
|
|
|
|
ret = HDstrcmp (buf1, buf2);
|
|
|
|
|
|
|
|
/* if "buf1" != "buf2" then the links are "different" */
|
|
|
|
nfound = (ret != 0) ? 1 : 0;
|
|
|
|
|
|
|
|
if (print_objname (options, nfound))
|
|
|
|
parallel_print("Link: <%s> and <%s>\n", path1, path2);
|
|
|
|
|
|
|
|
if (buf1)
|
|
|
|
{
|
|
|
|
free (buf1);
|
|
|
|
buf1 = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buf2)
|
|
|
|
{
|
|
|
|
free (buf2);
|
|
|
|
buf2 = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
nfound = 0;
|
|
|
|
if (options->m_verbose)
|
|
|
|
{
|
|
|
|
parallel_print("Comparison not supported: <%s> and <%s> are of type %s\n",
|
|
|
|
path1, path2, get_type (type));
|
|
|
|
options->not_cmp=1;
|
2005-08-14 04:53:35 +08:00
|
|
|
}
|
2005-06-29 00:25:42 +08:00
|
|
|
|
|
|
|
break;
|
2005-01-27 07:03:29 +08:00
|
|
|
}
|
2003-03-26 22:23:48 +08:00
|
|
|
|
2003-10-23 05:30:19 +08:00
|
|
|
|
2005-01-27 07:03:29 +08:00
|
|
|
out:
|
2003-05-31 06:38:46 +08:00
|
|
|
|
2005-02-08 13:42:49 +08:00
|
|
|
/* close */
|
|
|
|
/* disable error reporting */
|
|
|
|
H5E_BEGIN_TRY
|
|
|
|
{
|
2005-06-29 00:25:42 +08:00
|
|
|
H5Tclose (type1_id);
|
|
|
|
H5Tclose (type2_id);
|
|
|
|
H5Gclose (grp1_id);
|
|
|
|
H5Tclose (grp2_id);
|
|
|
|
/* enable error reporting */
|
2005-02-08 13:42:49 +08:00
|
|
|
}
|
|
|
|
H5E_END_TRY;
|
2003-05-08 06:28:09 +08:00
|
|
|
|
2005-02-08 13:42:49 +08:00
|
|
|
if (buf1)
|
2005-06-29 00:25:42 +08:00
|
|
|
free (buf1);
|
2005-02-08 13:42:49 +08:00
|
|
|
if (buf2)
|
2005-06-29 00:25:42 +08:00
|
|
|
free (buf2);
|
2003-05-08 06:28:09 +08:00
|
|
|
|
2005-02-08 13:42:49 +08:00
|
|
|
return nfound;
|
2005-01-27 07:03:29 +08:00
|
|
|
}
|
2005-02-07 07:45:15 +08:00
|
|
|
|
|
|
|
|