* Snapshot version 1.12 release 1-3. Update version to 1.12.1-4. * First cut of the H5 public API documentation. (#80) * First cut of the H5 public API documentation. * Added H5Z "bonus track." * Applied Quincey's patch. * Added the missing patches from Quincey's original patch. * H5PL (complete) and basic H5VL API documentation. * Added H5I API docs. * Added H5L API docs. * First installment from Elena's H5T batch. * Second installment of Elena's H5T batch. * Final installment of Elena's H5T batch. * Full set of current H5F documentation. (#105) * First cut of the H5 public API documentation. * Added H5Z "bonus track." * Applied Quincey's patch. * Added the missing patches from Quincey's original patch. * H5PL (complete) and basic H5VL API documentation. * Added H5I API docs. * Added H5L API docs. * First installment from Elena's H5T batch. * Second installment of Elena's H5T batch. * Final installment of Elena's H5T batch. * Migrated documentation for SWMR functions. * Catching up on MDC functions. * Integrated the H5F MDC function documentation. * Added MDC and parallel H5F functions. * Slightly updated main page. * Added doxygen/dox/H5AC_cache_config_t.dox to MANIFEST. * Doxygen - added (mostly) beginner functions (#112) * Doxygen - added (mostly) beginner functions * Removed duplicate H5Pset_szip function * Add src/H5module.h to MANIFEST. * close #195. (#196) * Update HDF5PluginMacros.cmake * Update HDF5PluginMacros.cmake * Avoid aligned access for references by decoding into temporary buffer and then copying the result into the actual buffer. Update test to be more thorough with using compound datatype fields everywhere. (#206) * Modify temporary rpath for testing in java example scripts. (#230) * Fix undefined left shifting of negative numbers (#338) Undefined Bahavior Sanitizer errored here about left shifting negative numbers. * Fixes various warnings noticed on Windows (#425) * Fixes various warnings noticed on Windows - Adds a prototype for our implementation of vasprintf - Return type of H5_get_utf16_str() is now non-const - Fixes possible uninitialized return type in Wremove_utf8 - Better isolation of fork() code in accum.c:test_swmr_write_big() - Better isolation of non-zlib code in dsets.c:test_filter_delete() - Removed unused variable in trefer.c:test_reference_cmpnd_obj() * Fixes clang-format issues * Applied clang-tidy readability-non-const-parameter warning fixes auto… (#429) * Automatically applied clang-tidy readability-avoid-const-params-in-decls fixes Removes useless const declarations. * Fixed most readability-non-const-parameter warnings These changes were made automatically by clang-tidy, but I manually reverted the changes related to the H5Z_func_t signature. * Reformat source with clang v10.0.1. Co-authored-by: Larry Knox <lrknox@hdfgroup.org> * Added C++11 override keyword where appropriate (#433) Added H5_OVERRIDE macro for compatibility with both C++11 and older. * Various clang tidy warning fixes (#448) * Fixed clang-tidy bugprone-reserved-identifier warnings * Fixed clang-tidy bugprone-assert-side-effect warnings * Fixed clang-tidy bugprone-copy-constructor-init warning * Fixed clang-tidy readability-redundant-preprocessor warning For error_test.c the removed code was already dead, because it was in the else of an `#if H5_USE_16_API` block. Based on H5Location.h, I think p_get_ref_obj_type was meant to be in `#ifndef DOXYGEN_SHOULD_SKIP_THIS` and an `#endif` was missing. Similarly, in the header, getObjTypeByIdx is only in H5_NO_DEPRECATED_SYMBOLS, not DOXYGEN_SHOULD_SKIP_THIS. * Fixed clang-tidy readability-redundant-string-init warnings * Fixed some clang-tidy performance-type-promotion-in-math-fn warnings * Fixed clang-tidy performance-unnecessary-value-param warnings * Reformat source with clang v10.0.1. Co-authored-by: Larry Knox <lrknox@hdfgroup.org> * Removed checks/workarounds for pre-C++89 compatibility (#449) After 30+ years, just assume that the following exist: - extension-less includes - namespaces - std:: - static_cast - bool * Fixed all clang-tidy bugprone-suspicious-string-compare warnings (#451) * Fixed all clang-tidy bugprone-suspicious-string-compare warnings This change was generated entirely by clang-tidy itself. * Reformat code with clang v10.0.1. Co-authored-by: Larry Knox <lrknox@hdfgroup.org> * Remove 2 functions incorrectly merged from develop in a cherry-pick merge of PR #451. * Minor parallel improvements (#519) * Improve MPI error reporting, handled failed operations in parallel tests more nicely, and clean up MPI_Allreduce for determining whether to break collective I/O * Committing clang-format changes Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Clean up MPI-IO VFD tracing support (#520) * Clean up tracing support * Committing clang-format changes Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Brings the native implementation of H5Fdelete() from Bitbucket (#524) * Committing clang-format changes * Brings the native VFD H5Fdelete() implementation from Bitbucket Only brings the 'del' callbacks, not the 'open/close' scheme. * Formatter changes * Committing clang-format changes * Fixes direct VFD callback name * Removes UNUSED macro from family API call * Adds barrier and rank 0 check to MPI-I/O VFD delete * Revert "Adds barrier and rank 0 check to MPI-I/O VFD delete" This reverts commit909765f759. * Revert "Revert "Adds barrier and rank 0 check to MPI-I/O VFD delete"" This reverts commit9b04bef115. * Adds a second barrier after the delete in MPI-I/O VFD * Only delete files in the core VFD when the backing store flag is set * Fixes string issues in multi VFD Also, h5test.c cleanup code now uses H5Fdelete(). * Formatted source * Rework fapl checks for MPI-I/O VFD delete callback Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Minor warning fixes in develop (#526) * Committing clang-format changes * Minor warning fixes Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Removes implementation of my_strdup() from the multi VFD (#527) * Committing clang-format changes * Removes my_strdup() from the multi VFD * Use strdup directly when memory sanity checks are off Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Removes dead H5ST package from the library (#528) * Committing clang-format changes * Removes the unused H5ST package from the library Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Fix HDFFV-11232 (#530) * fixed missed closing of a dataset * fixed missed closing of a dataset * fixed typo in error return * Committing clang-format changes * minor edits * code format * Committing clang-format changes * code format * minor edit * added H5fortkit dependency for H5VLff.F90, HDFFV-11232 Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Fixes incorrect usage of H5I_BADID (#554) * Committing clang-format changes * Fixes incorrect use of H5I_BADID Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Fixes a segfault when H5Pset_mdc_log_options is called multiple times on a fapl (#601) * Committing clang-format changes * Fixes a segfault when H5Pset_mdc_log_options() is called multiple times An internal string is incorrectly freed when the API call is invoked multiple times on a property list, which will usually cause a segfault to occur. On the first call the log location is NULL so the problem doesn't occur. Fixes HDFFV-11239 * Fixes typos Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Fix for a segfault when H5Pset_fapl_log is passed an invalid fapl ID (#607) * Committing clang-format changes * Fixes an issue where H5Pset_fapl_log sefaults when passed an invalid fapl ID This was due to a pointer-containing struct being memset after the first internal API call. If the first call failed, the error condition would check if the pointer was not NULL and then attempt to free it if not. This would lead to the freeing of a wild pointer if an invalid fapl ID were passed in. This was fixed by reordering the memset and adding a test to ensure the problem stays fixed. Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Fixes crashes when size_hint > UINT32_MAX is passed to H5Gcreate1 (#611) * Committing clang-format changes * Fixes incorrect size_hint handling in H5Gcreate1 * Updates the size hint type for group creation * Updates the RELEASE.txt note * Revert "Updates the RELEASE.txt note" This reverts commit3df386acca. * Reverts previous behavior to use a uint32_t struct field * Updates RELEASE.txt Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Revert "Brings the native implementation of H5Fdelete() from Bitbucket (#524)" This reverts commit38d1b121ae. * Removed mentions of Wdeclaration-after-statement now that C99 is requ… (#447) * Removed mentions of Wdeclaration-after-statement now that C99 is required * Remove -Werror=declaration-after-statement from error-general file. Co-authored-by: Larry Knox <lrknox@hdfgroup.org> * Made private my_yyinput function static (#618) This prevents it being exported as a public symbol. * Adds const to a few global variables (#623) * Committing clang-format changes * Adds consts to a few global variables Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * (fix) Segmentation fault when using a compound type. (#143) * (fix) Segmentation fault when using a compound type. In the case when a compounded attribute is written to dataset followed by writing the data with a data transform function to the dataset will result in a segmentation fault. It turns out the data is classified as compounded while it is not. Now, the state is always reset first to not compounded followed by the existing check if the variable is compounded. * (fix) Removed undesired comment lines. * (fix) Segmentation fault when using a compound type: added test. * (fix) Added the missing cmpd_transform.c file to MANIFEST. * (fix) cmpd_dtransform test: autotools and source header. Added the cmp_dtransform test to the autotools configuration and updated the HDF Group copyright header. Co-authored-by: Jan-Willem Blokland <Jan-Willem.Blokland@Shell.com> * (fix) H5Z_xform_create function and scientific notation (#144) * (fix) H5Z_xform_create function and scientific notation Implemented a more sophisticated check to support scientific notation in the expression of the H5Zset_data_transform function. * (fix) H5Z_xform_create and scientific notation: Added test. Added a test to demonstrate that the parsing of expression which includes scientific notation works correctly. Improved inline comment. Co-authored-by: Jan-Willem Blokland <Jan-Willem.Blokland@Shell.com> * Committing clang-format changes * Fix H5Eget_auto2/H5Eauto_is_v2 to not clear error stack (#625) * Cleanup tools debug build warnings (#627) * OESS-98 convert plugin option to FetchContent, add tests * Fixes for pkcfg files because of plugin option * OESS-98 fix tools test for plugins * Keep doxygen comments under 100 chars long - format hint * Whitespace * HDFFV-11144 - Reclassify CMake messages * HDFFV-11099/11100 added help text * Reworked switch statement to compare string instead * Fix typo * Update CDash mode * Correct name of threadsafe * Correct option name * Undo accidental commit * Note LLVM 10 to 11 format default changes * Update format plugin * Undo clang-format version 11 changes * One more correction * Update supported platforms * Revert whitespace changes * Correct whitespace * Changes from PR#3 * HDFFV-11213 added option to control gcc10 warnings diagnostics * HDFFV-11212 Use the new references correctly in JNI utility and tests * format source * Fix typo * Add new test file * HDFFV-11212 - update test and remove unused arg * Minor non-space formatting changes * Use H5I_INVALID_ID instead of "-1" * source formatting * add missing testfile, update jni function * Undo commit of debug code * remove mislocated file * Fix h5repack test for handling of fapls and id close * Update h5diff test files usage text * HDFFV-11212 add new ref tests for JNI export dataset * src format update * Remove blank line typo * src format typo * long double requires %Lg * Another long double foramt specifer S.B. %Lg * issue with t128bit test * Windows issue with h5dump and type. * Fix review issues * refactor function nesting and fix error checks * format fixes * Remove untested functions and javadoc quiet comments * Restore TRY block. * Change string append errors to memory exception * revert to H5_JNI_FATAL_ERROR - support functions need work * Add assertion error for h5util functions * remove duplicate function * format fix * Revert HD function error handling * Update copyright comments * GH #386 java folder copyright corrections * Whitespace * GH #359 implement and fix tools 1.6 API usage * remove excessive comments * Flip inits to correct ifdef section * rework ifdef to be simpler * format issue * Reformat ifdef inits * remove static attribute * format compliance * Update names * Revert because logic relies on float not being int * Changes noticed from creating merge of #412 * Double underscore change * Correct compiler version variable used * Remove header guard underscores * Whitespace cleanup * Split format source and commit changes on repo push * remove pre-split setting * Change windows TS to use older VS. * correct window os name * HDFFV-11212 JNI export util and Javadoc * Suggested review changes * Another change found * Committing clang-format changes * HDFFV-11113 long double in tools * HDFFV-11113 add note * Disable long double tests for now * HDFFV-11228 remove arbitrary CMake warning groups. * Make each flag a string * Some Javadoc warning fixes * Updated javadoc fixes * # WARNING: head commit changed in the meantime HDFFV-11229 Fix long double usage in tools and java Changed h5dump and h5ls to just print 128-bit for long double type. Added test and file for dataset and attributes with all three float types. * Committing clang-format changes * HDFFV-11229 Add release note * HDFFV-11229 windows testfile needed * fix typo * Remove non supported message text * HDFFV-11229 - change ldouble test to check both native and general * HDFFV-11229 add second file compare * HDFFV-11229 fix reference file * HDFFV-11229 autotools check two refs * HDFFV-11229 revert back to removal of NATIVE_LDOUBLE in tools output * Committing clang-format changes * Update release note * Update attribute type of ref file * Change source of ninja for macs * try port instead of brew * Recommended is to use brew. * Undo non long double changes * remove unneeded file * Fix perl and doxygen CMake code * Add "option" command for clang options * Rework CMake add_custom to use the BYPRODUCTS argument * Add stamp files to BYPRODUCTS * Only one copy of file exists * Fix custom cmmand depends targets * Fix fortran custom command DEPENDS * Add LD_LIBRARY_PATH to tests * Add custom target for DEPENDS * Add h5detect conditionaly to generated target DEPENDS * Correct DEPENDS targets * Parallel builds need the mpi compiler for pkgconfig scripts. * install only if MPI build * Fortran target depends * Remove incorrect source attribute * doxygen adjustments * doxygen build updates * Correct version * Correct function version - function has been merged to 1.12 * Correct version string for map functions * Cleanup warnings for tools debug builds Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * h5diff subset indexing (#628) * OESS-98 convert plugin option to FetchContent, add tests * Fixes for pkcfg files because of plugin option * OESS-98 fix tools test for plugins * Keep doxygen comments under 100 chars long - format hint * Whitespace * HDFFV-11144 - Reclassify CMake messages * HDFFV-11099/11100 added help text * Reworked switch statement to compare string instead * Fix typo * Update CDash mode * Correct name of threadsafe * Correct option name * Undo accidental commit * Note LLVM 10 to 11 format default changes * Update format plugin * Undo clang-format version 11 changes * One more correction * Update supported platforms * Revert whitespace changes * Correct whitespace * Changes from PR#3 * HDFFV-11213 added option to control gcc10 warnings diagnostics * HDFFV-11212 Use the new references correctly in JNI utility and tests * format source * Fix typo * Add new test file * HDFFV-11212 - update test and remove unused arg * Minor non-space formatting changes * Use H5I_INVALID_ID instead of "-1" * source formatting * add missing testfile, update jni function * Undo commit of debug code * remove mislocated file * Fix h5repack test for handling of fapls and id close * Update h5diff test files usage text * HDFFV-11212 add new ref tests for JNI export dataset * src format update * Remove blank line typo * src format typo * long double requires %Lg * Another long double foramt specifer S.B. %Lg * issue with t128bit test * Windows issue with h5dump and type. * Fix review issues * refactor function nesting and fix error checks * format fixes * Remove untested functions and javadoc quiet comments * Restore TRY block. * Change string append errors to memory exception * revert to H5_JNI_FATAL_ERROR - support functions need work * Add assertion error for h5util functions * remove duplicate function * format fix * Revert HD function error handling * Update copyright comments * GH #386 java folder copyright corrections * Whitespace * GH #359 implement and fix tools 1.6 API usage * remove excessive comments * Flip inits to correct ifdef section * rework ifdef to be simpler * format issue * Reformat ifdef inits * remove static attribute * format compliance * Update names * Revert because logic relies on float not being int * Changes noticed from creating merge of #412 * Double underscore change * Correct compiler version variable used * Remove header guard underscores * Whitespace cleanup * Split format source and commit changes on repo push * remove pre-split setting * Change windows TS to use older VS. * correct window os name * HDFFV-11212 JNI export util and Javadoc * Suggested review changes * Another change found * Committing clang-format changes * HDFFV-11113 long double in tools * HDFFV-11113 add note * Disable long double tests for now * HDFFV-11228 remove arbitrary CMake warning groups. * Make each flag a string * Some Javadoc warning fixes * Updated javadoc fixes * # WARNING: head commit changed in the meantime HDFFV-11229 Fix long double usage in tools and java Changed h5dump and h5ls to just print 128-bit for long double type. Added test and file for dataset and attributes with all three float types. * Committing clang-format changes * HDFFV-11229 Add release note * HDFFV-11229 windows testfile needed * fix typo * Remove non supported message text * HDFFV-11229 - change ldouble test to check both native and general * HDFFV-11229 add second file compare * HDFFV-11229 fix reference file * HDFFV-11229 autotools check two refs * HDFFV-11229 revert back to removal of NATIVE_LDOUBLE in tools output * Committing clang-format changes * Update release note * Update attribute type of ref file * Change source of ninja for macs * try port instead of brew * Recommended is to use brew. * Undo non long double changes * remove unneeded file * Fix perl and doxygen CMake code * Add "option" command for clang options * Rework CMake add_custom to use the BYPRODUCTS argument * Add stamp files to BYPRODUCTS * Only one copy of file exists * Fix custom cmmand depends targets * Fix fortran custom command DEPENDS * Add LD_LIBRARY_PATH to tests * Add custom target for DEPENDS * Add h5detect conditionaly to generated target DEPENDS * Correct DEPENDS targets * Parallel builds need the mpi compiler for pkgconfig scripts. * install only if MPI build * Fortran target depends * Remove incorrect source attribute * doxygen adjustments * doxygen build updates * Correct version * Correct function version - function has been merged to 1.12 * Correct version string for map functions * Cleanup warnings for tools debug builds * TRILAB-227 - fix indexing for h5diff selections * Correct location of pos to index function call Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Removes gratuitous (double)x.yF casts (#632) * Committing clang-format changes * Removes gratuitous (double)x.yF casts * Committing clang-format changes Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Cleans up a const warning left over from previous constification (#633) * Committing clang-format changes * Adds consts to a few global variables * Cleans up a const warning left over from previous constification Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Purges UFAIL from the library (#637) * Committing clang-format changes * Purges UFAIL from the library * H5HL_insert change requested in PR Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Bmr dev hdffv 11223 (#640) * Fixed HDFFV-11223 (CVE-2018-14460) Description - Added checks against buffer size to prevent segfault, in case of data corruption, for sdim->size and sdim->max. - Renamed data files in an existing test to shorten their length as agreed with other developers previously. Platforms tested: Linux/64 (jelly) * Committing clang-format changes * Updated for test files * Updated for HDFFV-11223 Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> * Revert "Fix H5Eget_auto2/H5Eauto_is_v2 to not clear error stack (#625)" This reverts commit7a68286284. Co-authored-by: Gerd Heber <gheber@hdfgroup.org> Co-authored-by: bljhdf <58825073+bljhdf@users.noreply.github.com> Co-authored-by: H. Joe Lee <hyoklee@hdfgroup.org> Co-authored-by: Quincey Koziol <quincey@koziol.cc> Co-authored-by: Sean McBride <sean@rogue-research.com> Co-authored-by: Dana Robinson <43805+derobins@users.noreply.github.com> Co-authored-by: Quincey Koziol <koziol@lbl.gov> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Scot Breitenfeld <brtnfld@hdfgroup.org> Co-authored-by: Jan-Willem Blokland <J.W.S.Blokland@XS4All.nl> Co-authored-by: Jan-Willem Blokland <Jan-Willem.Blokland@Shell.com> Co-authored-by: jhendersonHDF <jhenderson@hdfgroup.org> Co-authored-by: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Co-authored-by: bmribler <39579120+bmribler@users.noreply.github.com>
1231 lines
53 KiB
C
1231 lines
53 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* Copyright by The HDF Group. *
|
|
* 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 COPYING file, which can be found at the root of the source code *
|
|
* distribution tree, or in https://www.hdfgroup.org/licenses. *
|
|
* If you do not have access to either file, you may request a copy from *
|
|
* help@hdfgroup.org. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
#include "H5private.h"
|
|
#include "h5tools.h"
|
|
#include "h5tools_utils.h"
|
|
#include "h5diff.h"
|
|
#include "ph5diff.h"
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: diff_dataset
|
|
*
|
|
* Purpose: check for comparable datasets and read into a compatible
|
|
* memory type
|
|
*
|
|
* Return: Number of differences found
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
hsize_t
|
|
diff_dataset(hid_t file1_id, hid_t file2_id, const char *obj1_name, const char *obj2_name, diff_opt_t *opts)
|
|
{
|
|
int status = -1;
|
|
hid_t did1 = H5I_INVALID_HID;
|
|
hid_t did2 = H5I_INVALID_HID;
|
|
hid_t dcpl1 = H5I_INVALID_HID;
|
|
hid_t dcpl2 = H5I_INVALID_HID;
|
|
hsize_t nfound = 0;
|
|
diff_opt_t diff_opts;
|
|
diff_err_t ret_value = opts->err_stat;
|
|
|
|
H5TOOLS_START_DEBUG(" - errstat:%d", opts->err_stat);
|
|
diff_opts = *opts;
|
|
diff_opts.obj_name[0] = NULL;
|
|
diff_opts.obj_name[1] = NULL;
|
|
|
|
H5TOOLS_DEBUG("obj_names: %s - %s", obj1_name, obj2_name);
|
|
/*-------------------------------------------------------------------------
|
|
* open the handles
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
/* Open the datasets */
|
|
if ((did1 = H5Dopen2(file1_id, obj1_name, H5P_DEFAULT)) < 0) {
|
|
parallel_print("Cannot open dataset <%s>\n", obj1_name);
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Dopen2 first dataset failed");
|
|
}
|
|
if ((did2 = H5Dopen2(file2_id, obj2_name, H5P_DEFAULT)) < 0) {
|
|
parallel_print("Cannot open dataset <%s>\n", obj2_name);
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Dopen2 second dataset failed");
|
|
}
|
|
|
|
if ((dcpl1 = H5Dget_create_plist(did1)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Dget_create_plist first dataset failed");
|
|
if ((dcpl2 = H5Dget_create_plist(did2)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Dget_create_plist second dataset failed");
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* check if the dataset creation property list has filters that
|
|
* are not registered in the current configuration
|
|
* 1) the external filters GZIP and SZIP might not be available
|
|
* 2) the internal filters might be turned off
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
H5TOOLS_DEBUG("h5tools_canreadf then diff_datasetid");
|
|
if ((status = h5tools_canreadf((opts->mode_verbose ? obj1_name : NULL), dcpl1) == 1) &&
|
|
(status = h5tools_canreadf((opts->mode_verbose ? obj2_name : NULL), dcpl2) == 1))
|
|
nfound = diff_datasetid(did1, did2, obj1_name, obj2_name, &diff_opts);
|
|
else if (status < 0) {
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "h5tools_canreadf failed");
|
|
}
|
|
else {
|
|
ret_value = 1;
|
|
diff_opts.not_cmp = 1;
|
|
}
|
|
|
|
done:
|
|
opts->print_header = diff_opts.print_header;
|
|
opts->not_cmp = diff_opts.not_cmp;
|
|
opts->err_stat = diff_opts.err_stat | ret_value;
|
|
|
|
/* disable error reporting */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(dcpl1);
|
|
H5Pclose(dcpl2);
|
|
H5Dclose(did1);
|
|
H5Dclose(did2);
|
|
/* enable error reporting */
|
|
}
|
|
H5E_END_TRY;
|
|
|
|
H5TOOLS_ENDDEBUG(":%d - errstat:%d", nfound, opts->err_stat);
|
|
return nfound;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: diff_datasetid
|
|
*
|
|
* Purpose: check for comparable datasets and read into a compatible
|
|
* memory type
|
|
*
|
|
* Return: Number of differences found
|
|
*
|
|
* October 2006: Read by hyperslabs for big datasets.
|
|
*
|
|
* A threshold of H5TOOLS_MALLOCSIZE (128 MB) is the limit upon which I/O hyperslab is done
|
|
* i.e., if the memory needed to read a dataset is greater than this limit,
|
|
* then hyperslab I/O is done instead of one operation I/O
|
|
* For each dataset, the memory needed is calculated according to
|
|
*
|
|
* memory needed = number of elements * size of each element
|
|
*
|
|
* if the memory needed is lower than H5TOOLS_MALLOCSIZE, then the following operations
|
|
* are done
|
|
*
|
|
* H5Dread( input_dataset1 )
|
|
* H5Dread( input_dataset2 )
|
|
*
|
|
* with all elements in the datasets selected. If the memory needed is greater than
|
|
* H5TOOLS_MALLOCSIZE, then the following operations are done instead:
|
|
*
|
|
* a strip mine is defined for each dimension k (a strip mine is defined as a
|
|
* hyperslab whose size is memory manageable) according to the formula
|
|
*
|
|
* (1) strip_mine_size[k ] = MIN(dimension[k ], H5TOOLS_BUFSIZE / size of memory type)
|
|
*
|
|
* where H5TOOLS_BUFSIZE is a constant currently defined as 1MB. This formula assures
|
|
* that for small datasets (small relative to the H5TOOLS_BUFSIZE constant), the strip
|
|
* mine size k is simply defined as its dimension k, but for larger datasets the
|
|
* hyperslab size is still memory manageable.
|
|
* a cycle is done until the number of elements in the dataset is reached. In each
|
|
* iteration, two parameters are defined for the function H5Sselect_hyperslab,
|
|
* the start and size of each hyperslab, according to
|
|
*
|
|
* (2) hyperslab_size [k] = MIN(dimension[k] - hyperslab_offset[k], strip_mine_size [k])
|
|
*
|
|
* where hyperslab_offset [k] is initially set to zero, and later incremented in
|
|
* hyperslab_size[k] offsets. The reason for the operation
|
|
*
|
|
* dimension[k] - hyperslab_offset[k]
|
|
*
|
|
* in (2) is that, when using the strip mine size, it assures that the "remaining" part
|
|
* of the dataset that does not fill an entire strip mine is processed.
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
hsize_t
|
|
diff_datasetid(hid_t did1, hid_t did2, const char *obj1_name, const char *obj2_name, diff_opt_t *opts)
|
|
{
|
|
hid_t sid1 = H5I_INVALID_HID;
|
|
hid_t sid2 = H5I_INVALID_HID;
|
|
hid_t f_tid1 = H5I_INVALID_HID;
|
|
hid_t f_tid2 = H5I_INVALID_HID;
|
|
hid_t m_tid1 = H5I_INVALID_HID;
|
|
hid_t m_tid2 = H5I_INVALID_HID;
|
|
hid_t dcpl1 = H5I_INVALID_HID;
|
|
hid_t dcpl2 = H5I_INVALID_HID;
|
|
H5D_layout_t stl1 = -1;
|
|
H5D_layout_t stl2 = -1;
|
|
size_t m_size1;
|
|
size_t m_size2;
|
|
H5T_sign_t sign1;
|
|
H5T_sign_t sign2;
|
|
int rank1;
|
|
int rank2;
|
|
hsize_t nelmts1;
|
|
hsize_t nelmts2;
|
|
hsize_t dims1[H5S_MAX_RANK];
|
|
hsize_t dims2[H5S_MAX_RANK];
|
|
hsize_t maxdim1[H5S_MAX_RANK];
|
|
hsize_t maxdim2[H5S_MAX_RANK];
|
|
hsize_t storage_size1;
|
|
hsize_t storage_size2;
|
|
hsize_t nfound = 0; /* number of differences found */
|
|
int can_compare = 1; /* do diff or not */
|
|
void * buf1 = NULL;
|
|
void * buf2 = NULL;
|
|
void * sm_buf1 = NULL;
|
|
void * sm_buf2 = NULL;
|
|
hid_t sm_space1 = H5I_INVALID_HID; /*stripmine data space */
|
|
hid_t sm_space2 = H5I_INVALID_HID; /*stripmine data space */
|
|
size_t need; /* bytes needed for malloc */
|
|
int i, j;
|
|
unsigned int vl_data1 = 0; /*contains VL datatypes */
|
|
unsigned int vl_data2 = 0; /*contains VL datatypes */
|
|
diff_err_t ret_value = opts->err_stat;
|
|
|
|
H5TOOLS_START_DEBUG(" - errstat:%d", opts->err_stat);
|
|
/* Get the dataspace handle */
|
|
if ((sid1 = H5Dget_space(did1)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Dget_space failed");
|
|
|
|
/* Get rank */
|
|
if ((rank1 = H5Sget_simple_extent_ndims(sid1)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Sget_simple_extent_ndims failed");
|
|
|
|
/* Get the dataspace handle */
|
|
if ((sid2 = H5Dget_space(did2)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Dget_space failed");
|
|
|
|
/* Get rank */
|
|
if ((rank2 = H5Sget_simple_extent_ndims(sid2)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Sget_simple_extent_ndims failed");
|
|
|
|
/* Get dimensions */
|
|
if (H5Sget_simple_extent_dims(sid1, dims1, maxdim1) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Sget_simple_extent_dims failed");
|
|
|
|
/* Get dimensions */
|
|
if (H5Sget_simple_extent_dims(sid2, dims2, maxdim2) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Sget_simple_extent_dims failed");
|
|
H5TOOLS_DEBUG("rank: %ld - %ld", rank1, rank2);
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* get the file data type
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
/* Get the data type */
|
|
if ((f_tid1 = H5Dget_type(did1)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Dget_type failed");
|
|
|
|
/* Get the data type */
|
|
if ((f_tid2 = H5Dget_type(did2)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Dget_type failed");
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* get the storage layout type
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
if ((dcpl1 = H5Dget_create_plist(did1)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Dget_create_plist failed");
|
|
if ((stl1 = H5Pget_layout(dcpl1)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Pget_layout failed");
|
|
H5Pclose(dcpl1);
|
|
|
|
if ((dcpl2 = H5Dget_create_plist(did2)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Dget_create_plist failed");
|
|
if ((stl2 = H5Pget_layout(dcpl2)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Pget_layout failed");
|
|
H5Pclose(dcpl2);
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* check for empty datasets
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
H5TOOLS_DEBUG("check for empty datasets");
|
|
|
|
storage_size1 = H5Dget_storage_size(did1);
|
|
storage_size2 = H5Dget_storage_size(did2);
|
|
H5TOOLS_DEBUG("storage size: %ld - %ld", storage_size1, storage_size2);
|
|
|
|
if (storage_size1 == 0 || storage_size2 == 0) {
|
|
if (stl1 == H5D_VIRTUAL || stl2 == H5D_VIRTUAL) {
|
|
if ((opts->mode_verbose || opts->mode_list_not_cmp) && obj1_name && obj2_name)
|
|
parallel_print("Warning: <%s> or <%s> is a virtual dataset\n", obj1_name, obj2_name);
|
|
}
|
|
else {
|
|
if ((opts->mode_verbose || opts->mode_list_not_cmp) && obj1_name && obj2_name)
|
|
parallel_print("Not comparable: <%s> or <%s> is an empty dataset\n", obj1_name, obj2_name);
|
|
can_compare = 0;
|
|
opts->not_cmp = 1;
|
|
}
|
|
}
|
|
|
|
H5TOOLS_DEBUG("obj_names: %s - %s", obj1_name, obj2_name);
|
|
opts->obj_name[0] = NULL;
|
|
if (obj1_name) {
|
|
j = (int)HDstrlen(obj1_name);
|
|
H5TOOLS_DEBUG("obj1_name: %s - %d", obj1_name, j);
|
|
if (j > 0) {
|
|
opts->obj_name[0] = (char *)HDmalloc((size_t)j + 1);
|
|
HDstrncpy(opts->obj_name[0], obj1_name, (size_t)j + 1);
|
|
}
|
|
}
|
|
|
|
opts->obj_name[1] = NULL;
|
|
if (obj2_name) {
|
|
j = (int)HDstrlen(obj2_name);
|
|
H5TOOLS_DEBUG("obj2_name: %s - %d", obj2_name, j);
|
|
if (j > 0) {
|
|
opts->obj_name[1] = (char *)HDmalloc((size_t)j + 1);
|
|
HDstrncpy(opts->obj_name[1], obj2_name, (size_t)j + 1);
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* check for comparable TYPE and SPACE
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
if (diff_can_type(f_tid1, f_tid2, rank1, rank2, dims1, dims2, maxdim1, maxdim2, opts, 0) != 1)
|
|
can_compare = 0;
|
|
H5TOOLS_DEBUG("diff_can_type returned errstat:%d", opts->err_stat);
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* memory type and sizes
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
H5TOOLS_DEBUG("check for memory type and sizes");
|
|
if (H5Tget_class(f_tid1) == H5T_REFERENCE) {
|
|
if ((m_tid1 = H5Tcopy(H5T_STD_REF)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Tcopy(H5T_STD_REF) first ftype failed");
|
|
}
|
|
else {
|
|
if ((m_tid1 = H5Tget_native_type(f_tid1, H5T_DIR_DEFAULT)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Tget_native_type first ftype failed");
|
|
}
|
|
|
|
if (H5Tget_class(f_tid2) == H5T_REFERENCE) {
|
|
if ((m_tid2 = H5Tcopy(H5T_STD_REF)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Tcopy(H5T_STD_REF) second ftype failed");
|
|
}
|
|
else {
|
|
if ((m_tid2 = H5Tget_native_type(f_tid2, H5T_DIR_DEFAULT)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Tget_native_type second ftype failed");
|
|
}
|
|
|
|
m_size1 = H5Tget_size(m_tid1);
|
|
m_size2 = H5Tget_size(m_tid2);
|
|
H5TOOLS_DEBUG("type size: %ld - %ld", m_size1, m_size2);
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* check for different signed/unsigned types
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
if (can_compare) {
|
|
H5TOOLS_DEBUG("can_compare for sign");
|
|
sign1 = H5Tget_sign(m_tid1);
|
|
sign2 = H5Tget_sign(m_tid2);
|
|
if (sign1 != sign2) {
|
|
H5TOOLS_DEBUG("sign1 != sign2");
|
|
if ((opts->mode_verbose || opts->mode_list_not_cmp) && obj1_name && obj2_name) {
|
|
parallel_print("Not comparable: <%s> has sign %s ", obj1_name, get_sign(sign1));
|
|
parallel_print("and <%s> has sign %s\n", obj2_name, get_sign(sign2));
|
|
}
|
|
|
|
can_compare = 0;
|
|
opts->not_cmp = 1;
|
|
}
|
|
H5TOOLS_DEBUG("can_compare for sign - can_compare=%d opts->not_cmp=%d", can_compare, opts->not_cmp);
|
|
}
|
|
|
|
/* Check if type is either VLEN-data or VLEN-string to reclaim any
|
|
* VLEN memory buffer later
|
|
*/
|
|
if (TRUE == h5tools_detect_vlen(m_tid1))
|
|
vl_data1 = TRUE;
|
|
if (TRUE == h5tools_detect_vlen(m_tid2))
|
|
vl_data2 = TRUE;
|
|
H5TOOLS_DEBUG("h5tools_detect_vlen %d:%d - errstat:%d", vl_data1, vl_data2, opts->err_stat);
|
|
|
|
/*------------------------------------------------------------------------
|
|
* only attempt to compare if possible
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
if (can_compare) { /* it is possible to compare */
|
|
H5T_class_t tclass = H5Tget_class(f_tid1);
|
|
H5TOOLS_DEBUG("can_compare attempt");
|
|
|
|
/*-----------------------------------------------------------------
|
|
* get number of elements
|
|
*------------------------------------------------------------------
|
|
*/
|
|
nelmts1 = 1;
|
|
for (i = 0; i < rank1; i++)
|
|
nelmts1 *= dims1[i];
|
|
|
|
nelmts2 = 1;
|
|
for (i = 0; i < rank2; i++)
|
|
nelmts2 *= dims2[i];
|
|
|
|
H5TOOLS_DEBUG("nelmts: %ld - %ld", nelmts1, nelmts2);
|
|
|
|
if (tclass != H5T_ARRAY) {
|
|
/*-----------------------------------------------------------------
|
|
* "upgrade" the smaller memory size
|
|
*------------------------------------------------------------------
|
|
*/
|
|
H5TOOLS_DEBUG("NOT H5T_ARRAY, upgrade the smaller memory size?");
|
|
if (FAIL == match_up_memsize(f_tid1, f_tid2, &m_tid1, &m_tid2, &m_size1, &m_size2))
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "match_up_memsize failed");
|
|
H5TOOLS_DEBUG("m_size: %ld - %ld", m_size1, m_size2);
|
|
opts->rank = rank1;
|
|
for (i = 0; i < rank1; i++)
|
|
opts->dims[i] = dims1[i];
|
|
opts->m_size = m_size1;
|
|
opts->m_tid = m_tid1;
|
|
opts->nelmts = nelmts1;
|
|
need = (size_t)(nelmts1 * m_size1); /* bytes needed */
|
|
}
|
|
else {
|
|
H5TOOLS_DEBUG("Array dims: %d - %d", dims1[0], dims2[0]);
|
|
/* Compare the smallest array, but create the largest buffer */
|
|
if (m_size1 <= m_size2) {
|
|
opts->rank = rank1;
|
|
for (i = 0; i < rank1; i++)
|
|
opts->dims[i] = dims1[i];
|
|
opts->m_size = m_size1;
|
|
opts->m_tid = m_tid1;
|
|
opts->nelmts = nelmts1;
|
|
need = (size_t)(nelmts2 * m_size2); /* bytes needed */
|
|
}
|
|
else {
|
|
opts->rank = rank2;
|
|
for (i = 0; i < rank2; i++)
|
|
opts->dims[i] = dims2[i];
|
|
opts->m_size = m_size2;
|
|
opts->m_tid = m_tid2;
|
|
opts->nelmts = nelmts2;
|
|
need = (size_t)(nelmts1 * m_size1); /* bytes needed */
|
|
}
|
|
}
|
|
opts->hs_nelmts = opts->nelmts;
|
|
H5TOOLS_DEBUG("need: %ld", need);
|
|
/* print names */
|
|
H5TOOLS_DEBUG("obj_names: %s - %s", obj1_name, obj2_name);
|
|
|
|
if (opts->obj_name[0] != NULL)
|
|
HDfree(opts->obj_name[0]);
|
|
opts->obj_name[0] = NULL;
|
|
if (opts->obj_name[1] != NULL)
|
|
HDfree(opts->obj_name[1]);
|
|
opts->obj_name[1] = NULL;
|
|
|
|
if (obj1_name)
|
|
opts->obj_name[0] = HDstrdup(diff_basename(obj1_name));
|
|
if (obj2_name)
|
|
opts->obj_name[1] = HDstrdup(diff_basename(obj2_name));
|
|
H5TOOLS_DEBUG("obj_names: %s - %s", opts->obj_name[0], opts->obj_name[1]);
|
|
|
|
H5TOOLS_DEBUG("read/compare");
|
|
/*----------------------------------------------------------------
|
|
* read/compare
|
|
*-----------------------------------------------------------------
|
|
*/
|
|
if (need < H5TOOLS_MALLOCSIZE) {
|
|
buf1 = HDmalloc(need);
|
|
buf2 = HDmalloc(need);
|
|
} /* end if */
|
|
|
|
/* Assume entire data space to be printed */
|
|
init_acc_pos((unsigned)opts->rank, opts->dims, opts->acc, opts->pos, opts->p_min_idx);
|
|
|
|
for (i = 0; i < opts->rank; i++) {
|
|
opts->p_max_idx[i] = opts->dims[i];
|
|
}
|
|
|
|
if (buf1 != NULL && buf2 != NULL && opts->sset[0] == NULL && opts->sset[1] == NULL) {
|
|
H5TOOLS_DEBUG("buf1 != NULL && buf2 != NULL");
|
|
H5TOOLS_DEBUG("H5Dread did1");
|
|
if (H5Dread(did1, m_tid1, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf1) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Dread failed");
|
|
H5TOOLS_DEBUG("H5Dread did2");
|
|
if (H5Dread(did2, m_tid2, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf2) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Dread failed");
|
|
|
|
/* initialize the current stripmine position; this is necessary to print the array indices */
|
|
for (j = 0; j < opts->rank; j++)
|
|
opts->sm_pos[j] = (hsize_t)0;
|
|
|
|
/* array diff */
|
|
nfound = diff_array(buf1, buf2, opts, did1, did2);
|
|
H5TOOLS_DEBUG("diff_array ret nfound:%d - errstat:%d", nfound, opts->err_stat);
|
|
|
|
/* reclaim any VL memory, if necessary */
|
|
H5TOOLS_DEBUG("check vl_data1:%d", vl_data1);
|
|
if (vl_data1)
|
|
H5Treclaim(m_tid1, sid1, H5P_DEFAULT, buf1);
|
|
H5TOOLS_DEBUG("check vl_data2:%d", vl_data2);
|
|
if (vl_data2)
|
|
H5Treclaim(m_tid2, sid2, H5P_DEFAULT, buf2);
|
|
if (buf1 != NULL) {
|
|
HDfree(buf1);
|
|
buf1 = NULL;
|
|
}
|
|
if (buf2 != NULL) {
|
|
HDfree(buf2);
|
|
buf2 = NULL;
|
|
}
|
|
} /* end if */
|
|
else { /* possibly not enough memory, read/compare by hyperslabs */
|
|
hsize_t elmtno; /* counter */
|
|
int carry; /* counter carry value */
|
|
|
|
/* stripmine info */
|
|
hsize_t sm_size[H5S_MAX_RANK]; /* stripmine size */
|
|
hsize_t sm_block[H5S_MAX_RANK]; /* stripmine block size */
|
|
hsize_t sm_nbytes; /* bytes per stripmine */
|
|
hsize_t sm_nelmts1; /* elements per stripmine */
|
|
hsize_t sm_nelmts2; /* elements per stripmine */
|
|
hssize_t ssm_nelmts; /* elements temp */
|
|
|
|
/* hyperslab info */
|
|
hsize_t hs_offset1[H5S_MAX_RANK]; /* starting offset */
|
|
hsize_t hs_count1[H5S_MAX_RANK]; /* number of blocks */
|
|
hsize_t hs_block1[H5S_MAX_RANK]; /* size of blocks */
|
|
hsize_t hs_stride1[H5S_MAX_RANK]; /* stride */
|
|
hsize_t hs_size1[H5S_MAX_RANK]; /* size this pass */
|
|
hsize_t hs_offset2[H5S_MAX_RANK]; /* starting offset */
|
|
hsize_t hs_count2[H5S_MAX_RANK]; /* number of blocks */
|
|
hsize_t hs_block2[H5S_MAX_RANK]; /* size of blocks */
|
|
hsize_t hs_stride2[H5S_MAX_RANK]; /* stride */
|
|
hsize_t hs_size2[H5S_MAX_RANK]; /* size this pass */
|
|
hsize_t hs_nelmts1 = 0; /* elements in request */
|
|
hsize_t hs_nelmts2 = 0; /* elements in request */
|
|
hsize_t zero[8]; /* vector of zeros */
|
|
hsize_t low[H5S_MAX_RANK]; /* low bound of hyperslab */
|
|
hsize_t high[H5S_MAX_RANK]; /* higher bound of hyperslab */
|
|
|
|
H5TOOLS_DEBUG("reclaim any VL memory and free unused buffers");
|
|
if (buf1 != NULL) {
|
|
/* reclaim any VL memory, if necessary */
|
|
if (vl_data1)
|
|
H5Treclaim(m_tid1, sid1, H5P_DEFAULT, buf1);
|
|
HDfree(buf1);
|
|
buf1 = NULL;
|
|
}
|
|
if (buf2 != NULL) {
|
|
/* reclaim any VL memory, if necessary */
|
|
if (vl_data2)
|
|
H5Treclaim(m_tid2, sid2, H5P_DEFAULT, buf2);
|
|
HDfree(buf2);
|
|
buf2 = NULL;
|
|
}
|
|
|
|
/* the stripmine loop */
|
|
HDmemset(hs_offset1, 0, sizeof hs_offset1);
|
|
HDmemset(hs_stride1, 0, sizeof hs_stride1);
|
|
HDmemset(hs_count1, 0, sizeof hs_count1);
|
|
HDmemset(hs_block1, 0, sizeof hs_block1);
|
|
HDmemset(hs_size1, 0, sizeof hs_size1);
|
|
HDmemset(hs_offset2, 0, sizeof hs_offset2);
|
|
HDmemset(hs_stride2, 0, sizeof hs_stride2);
|
|
HDmemset(hs_count2, 0, sizeof hs_count2);
|
|
HDmemset(hs_block2, 0, sizeof hs_block2);
|
|
HDmemset(hs_size2, 0, sizeof hs_size2);
|
|
HDmemset(zero, 0, sizeof zero);
|
|
|
|
/* if subsetting was requested - initialize the subsetting variables */
|
|
H5TOOLS_DEBUG("compare by hyperslabs: opts->nelmts=%ld - opts->m_size=%ld", opts->nelmts,
|
|
opts->m_size);
|
|
if (opts->sset[0] != NULL) {
|
|
H5TOOLS_DEBUG("opts->sset[0] != NULL");
|
|
|
|
/* Check for valid settings - default if not specified */
|
|
if (!opts->sset[0]->start.data || !opts->sset[0]->stride.data || !opts->sset[0]->count.data ||
|
|
!opts->sset[0]->block.data) {
|
|
/* they didn't specify a ``stride'' or ``block''. default to 1 in all
|
|
* dimensions */
|
|
if (!opts->sset[0]->start.data) {
|
|
/* default to (0, 0, ...) for the start coord */
|
|
opts->sset[0]->start.data = (hsize_t *)HDcalloc((size_t)rank1, sizeof(hsize_t));
|
|
opts->sset[0]->start.len = (unsigned)rank1;
|
|
}
|
|
|
|
if (!opts->sset[0]->stride.data) {
|
|
opts->sset[0]->stride.data = (hsize_t *)HDcalloc((size_t)rank1, sizeof(hsize_t));
|
|
opts->sset[0]->stride.len = (unsigned)rank1;
|
|
for (i = 0; i < rank1; i++)
|
|
opts->sset[0]->stride.data[i] = 1;
|
|
}
|
|
|
|
if (!opts->sset[0]->count.data) {
|
|
opts->sset[0]->count.data = (hsize_t *)HDcalloc((size_t)rank1, sizeof(hsize_t));
|
|
opts->sset[0]->count.len = (unsigned)rank1;
|
|
for (i = 0; i < rank1; i++)
|
|
opts->sset[0]->count.data[i] = 1;
|
|
}
|
|
|
|
if (!opts->sset[0]->block.data) {
|
|
opts->sset[0]->block.data = (hsize_t *)HDcalloc((size_t)rank1, sizeof(hsize_t));
|
|
opts->sset[0]->block.len = (unsigned)rank1;
|
|
for (i = 0; i < rank1; i++)
|
|
opts->sset[0]->block.data[i] = 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* check for block overlap
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
for (i = 0; i < rank1; i++) {
|
|
if (opts->sset[0]->count.data[i] > 1) {
|
|
if (opts->sset[0]->stride.data[i] < opts->sset[0]->block.data[i]) {
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "wrong subset selection[0]; blocks overlap");
|
|
} /* end if */
|
|
} /* end if */
|
|
} /* end for */
|
|
}
|
|
|
|
/* Reset the total number of elements to the subset from the command */
|
|
opts->nelmts = 1;
|
|
for (i = 0; i < rank1; i++) {
|
|
hs_offset1[i] = opts->sset[0]->start.data[i];
|
|
hs_stride1[i] = opts->sset[0]->stride.data[i];
|
|
hs_count1[i] = opts->sset[0]->count.data[i];
|
|
hs_block1[i] = opts->sset[0]->block.data[i];
|
|
opts->nelmts *= hs_count1[i] * hs_block1[i];
|
|
hs_size1[i] = 0;
|
|
H5TOOLS_DEBUG("[%d]hs_offset1:%ld, hs_stride1:%ld, hs_count1:%ld, hs_block1:%ld", i,
|
|
hs_offset1[i], hs_stride1[i], hs_count1[i], hs_block1[i]);
|
|
}
|
|
}
|
|
if (opts->sset[1] != NULL) {
|
|
H5TOOLS_DEBUG("opts->sset[1] != NULL");
|
|
|
|
/* Check for valid settings - default if not specified */
|
|
if (!opts->sset[1]->start.data || !opts->sset[1]->stride.data || !opts->sset[1]->count.data ||
|
|
!opts->sset[1]->block.data) {
|
|
/* they didn't specify a ``stride'' or ``block''. default to 1 in all
|
|
* dimensions */
|
|
if (!opts->sset[1]->start.data) {
|
|
/* default to (0, 0, ...) for the start coord */
|
|
opts->sset[1]->start.data = (hsize_t *)HDcalloc((size_t)rank2, sizeof(hsize_t));
|
|
opts->sset[1]->start.len = (unsigned)rank2;
|
|
}
|
|
|
|
if (!opts->sset[1]->stride.data) {
|
|
opts->sset[1]->stride.data = (hsize_t *)HDcalloc((size_t)rank2, sizeof(hsize_t));
|
|
opts->sset[1]->stride.len = (unsigned)rank2;
|
|
for (i = 0; i < rank2; i++)
|
|
opts->sset[1]->stride.data[i] = 1;
|
|
}
|
|
|
|
if (!opts->sset[1]->count.data) {
|
|
opts->sset[1]->count.data = (hsize_t *)HDcalloc((size_t)rank2, sizeof(hsize_t));
|
|
opts->sset[1]->count.len = (unsigned)rank2;
|
|
for (i = 0; i < rank2; i++)
|
|
opts->sset[1]->count.data[i] = 1;
|
|
}
|
|
|
|
if (!opts->sset[1]->block.data) {
|
|
opts->sset[1]->block.data = (hsize_t *)HDcalloc((size_t)rank2, sizeof(hsize_t));
|
|
opts->sset[1]->block.len = (unsigned)rank2;
|
|
for (i = 0; i < rank2; i++)
|
|
opts->sset[1]->block.data[i] = 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* check for block overlap
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
for (i = 0; i < rank2; i++) {
|
|
if (opts->sset[1]->count.data[i] > 1) {
|
|
if (opts->sset[1]->stride.data[i] < opts->sset[1]->block.data[i]) {
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "wrong subset selection[1]; blocks overlap");
|
|
} /* end if */
|
|
} /* end if */
|
|
} /* end for */
|
|
}
|
|
|
|
for (i = 0; i < rank2; i++) {
|
|
hs_offset2[i] = opts->sset[1]->start.data[i];
|
|
hs_stride2[i] = opts->sset[1]->stride.data[i];
|
|
hs_count2[i] = opts->sset[1]->count.data[i];
|
|
hs_block2[i] = opts->sset[1]->block.data[i];
|
|
hs_size2[i] = 0;
|
|
H5TOOLS_DEBUG("[%d]hs_offset2:%ld, hs_stride2:%ld, hs_count2:%ld, hs_block2:%ld", i,
|
|
hs_offset2[i], hs_stride2[i], hs_count2[i], hs_block2[i]);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* determine the strip mine size and allocate a buffer. The strip mine is
|
|
* a hyperslab whose size is manageable.
|
|
*/
|
|
sm_nbytes = opts->m_size;
|
|
if (opts->rank > 0) {
|
|
for (i = opts->rank; i > 0; --i) {
|
|
hsize_t size = H5TOOLS_BUFSIZE / sm_nbytes;
|
|
if (size == 0) /* datum size > H5TOOLS_BUFSIZE */
|
|
size = 1;
|
|
H5TOOLS_DEBUG("opts->dims[%d]: %ld - size: %ld", i - 1, opts->dims[i - 1], size);
|
|
if (opts->sset[1] != NULL) {
|
|
sm_size[i - 1] = MIN(hs_block1[i - 1] * hs_count1[i - 1], size);
|
|
sm_block[i - 1] = MIN(hs_block1[i - 1], sm_size[i - 1]);
|
|
}
|
|
else {
|
|
sm_size[i - 1] = MIN(opts->dims[i - 1], size);
|
|
sm_block[i - 1] = sm_size[i - 1];
|
|
}
|
|
H5TOOLS_DEBUG("sm_size[%d]: %ld - sm_block:%ld", i - 1, sm_size[i - 1], sm_block[i - 1]);
|
|
sm_nbytes *= sm_size[i - 1];
|
|
H5TOOLS_DEBUG("sm_nbytes: %ld", sm_nbytes);
|
|
}
|
|
}
|
|
|
|
H5TOOLS_DEBUG("opts->nelmts: %ld", opts->nelmts);
|
|
for (elmtno = 0; elmtno < opts->nelmts; elmtno += opts->hs_nelmts) {
|
|
H5TOOLS_DEBUG("elmtno: %ld - hs_nelmts1: %ld", elmtno, hs_nelmts1);
|
|
|
|
if (NULL == (sm_buf1 = (unsigned char *)HDmalloc((size_t)sm_nbytes)))
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "Could not allocate buffer for strip-mine");
|
|
if (NULL == (sm_buf2 = (unsigned char *)HDmalloc((size_t)sm_nbytes)))
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "Could not allocate buffer for strip-mine");
|
|
|
|
/* calculate the hyperslab size */
|
|
/* initialize subset */
|
|
if (opts->rank > 0) {
|
|
if (opts->sset[0] != NULL) {
|
|
H5TOOLS_DEBUG("sset1 has data");
|
|
/* calculate the potential number of elements */
|
|
for (i = 0; i < rank1; i++) {
|
|
H5TOOLS_DEBUG("[%d]opts->dims: %ld - hs_offset1: %ld - sm_block: %ld", i,
|
|
opts->dims[i], hs_offset1[i], sm_block[i]);
|
|
hs_size1[i] = MIN(opts->dims[i] - hs_offset1[i], sm_block[i]);
|
|
H5TOOLS_DEBUG("hs_size1[%d]: %ld", i, hs_size1[i]);
|
|
}
|
|
if (H5Sselect_hyperslab(sid1, H5S_SELECT_SET, hs_offset1, hs_stride1, hs_count1,
|
|
hs_size1) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Sselect_hyperslab sid1 failed");
|
|
}
|
|
else {
|
|
for (i = 0, hs_nelmts1 = 1; i < rank1; i++) {
|
|
H5TOOLS_DEBUG("[%d]opts->dims: %ld - hs_offset1: %ld - sm_block: %ld", i,
|
|
opts->dims[i], hs_offset1[i], sm_block[i]);
|
|
hs_size1[i] = MIN(opts->dims[i] - hs_offset1[i], sm_block[i]);
|
|
H5TOOLS_DEBUG("hs_size1[%d]: %ld", i, hs_size1[i]);
|
|
hs_nelmts1 *= hs_size1[i];
|
|
H5TOOLS_DEBUG("hs_nelmts1:%ld *= hs_size1[%d]: %ld", hs_nelmts1, i, hs_size1[i]);
|
|
}
|
|
if (H5Sselect_hyperslab(sid1, H5S_SELECT_SET, hs_offset1, NULL, hs_size1, NULL) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Sselect_hyperslab sid1 failed");
|
|
}
|
|
|
|
if ((ssm_nelmts = H5Sget_select_npoints(sid1)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Sget_select_npoints failed");
|
|
sm_nelmts1 = (hsize_t)ssm_nelmts;
|
|
H5TOOLS_DEBUG("sm_nelmts1: %ld", sm_nelmts1);
|
|
hs_nelmts1 = sm_nelmts1;
|
|
|
|
if ((sm_space1 = H5Screate_simple(1, &sm_nelmts1, NULL)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Screate_simple failed");
|
|
|
|
if (H5Sselect_hyperslab(sm_space1, H5S_SELECT_SET, zero, NULL, &sm_nelmts1, NULL) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Sselect_hyperslab failed");
|
|
|
|
if (opts->sset[1] != NULL) {
|
|
H5TOOLS_DEBUG("sset2 has data");
|
|
for (i = 0; i < rank2; i++) {
|
|
H5TOOLS_DEBUG("[%d]opts->dims: %ld - hs_offset2: %ld - sm_block: %ld", i,
|
|
opts->dims[i], hs_offset2[i], sm_block[i]);
|
|
hs_size2[i] = MIN(opts->dims[i] - hs_offset2[i], sm_block[i]);
|
|
H5TOOLS_DEBUG("hs_size2[%d]: %ld", i, hs_size2[i]);
|
|
}
|
|
if (H5Sselect_hyperslab(sid2, H5S_SELECT_SET, hs_offset2, hs_stride2, hs_count2,
|
|
hs_size2) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Sselect_hyperslab sid2 failed");
|
|
}
|
|
else {
|
|
for (i = 0, hs_nelmts2 = 1; i < rank2; i++) {
|
|
H5TOOLS_DEBUG("[%d]opts->dims: %ld - hs_offset2: %ld - sm_block: %ld", i,
|
|
opts->dims[i], hs_offset2[i], sm_block[i]);
|
|
hs_size2[i] = MIN(opts->dims[i] - hs_offset2[i], sm_block[i]);
|
|
H5TOOLS_DEBUG("hs_size2[%d]: %ld", i, hs_size2[i]);
|
|
hs_nelmts2 *= hs_size2[i];
|
|
H5TOOLS_DEBUG("hs_nelmts2:%ld *= hs_size2[%d]: %ld", hs_nelmts2, i, hs_size2[i]);
|
|
}
|
|
if (H5Sselect_hyperslab(sid2, H5S_SELECT_SET, hs_offset2, NULL, hs_size2, NULL) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Sselect_hyperslab sid2 failed");
|
|
}
|
|
|
|
if ((ssm_nelmts = H5Sget_select_npoints(sid2)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Sget_select_npoints failed");
|
|
sm_nelmts2 = (hsize_t)ssm_nelmts;
|
|
H5TOOLS_DEBUG("sm_nelmts2: %ld", sm_nelmts2);
|
|
hs_nelmts2 = sm_nelmts2;
|
|
|
|
if ((sm_space2 = H5Screate_simple(1, &sm_nelmts2, NULL)) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Screate_simple failed");
|
|
|
|
if (H5Sselect_hyperslab(sm_space2, H5S_SELECT_SET, zero, NULL, &sm_nelmts2, NULL) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Sselect_hyperslab failed");
|
|
}
|
|
else
|
|
hs_nelmts1 = 1;
|
|
opts->hs_nelmts = hs_nelmts1;
|
|
H5TOOLS_DEBUG("hs_nelmts: %ld", opts->hs_nelmts);
|
|
|
|
/* read the data */
|
|
if (H5Dread(did1, m_tid1, sm_space1, sid1, H5P_DEFAULT, sm_buf1) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Dread failed");
|
|
if (H5Dread(did2, m_tid2, sm_space2, sid2, H5P_DEFAULT, sm_buf2) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Dread failed");
|
|
|
|
/* print array indices. get the lower bound of the hyperslab and calculate
|
|
the element position at the start of hyperslab */
|
|
if (H5Sget_select_bounds(sid1, low, high) < 0)
|
|
H5TOOLS_GOTO_ERROR(H5DIFF_ERR, "H5Sget_select_bounds failed");
|
|
/* initialize the current stripmine position; this is necessary to print the array indices */
|
|
for (j = 0; j < opts->rank; j++)
|
|
opts->sm_pos[j] = low[j];
|
|
|
|
/* Assume entire data space to be printed */
|
|
init_acc_pos((unsigned)opts->rank, opts->dims, opts->acc, opts->pos, opts->p_min_idx);
|
|
|
|
/* get array differences. in the case of hyperslab read, increment the number of differences
|
|
found in each hyperslab and pass the position at the beginning for printing */
|
|
nfound += diff_array(sm_buf1, sm_buf2, opts, did1, did2);
|
|
|
|
if (sm_buf1 != NULL) {
|
|
/* reclaim any VL memory, if necessary */
|
|
if (vl_data1)
|
|
H5Treclaim(m_tid1, sm_space1, H5P_DEFAULT, sm_buf1);
|
|
HDfree(sm_buf1);
|
|
sm_buf1 = NULL;
|
|
}
|
|
if (sm_buf2 != NULL) {
|
|
/* reclaim any VL memory, if necessary */
|
|
if (vl_data2)
|
|
H5Treclaim(m_tid2, sm_space2, H5P_DEFAULT, sm_buf2);
|
|
HDfree(sm_buf2);
|
|
sm_buf2 = NULL;
|
|
}
|
|
|
|
H5Sclose(sm_space1);
|
|
H5Sclose(sm_space2);
|
|
|
|
/* calculate the next hyperslab offset */
|
|
for (i = opts->rank, carry = 1; i > 0 && carry; --i) {
|
|
if (opts->sset[0] != NULL) {
|
|
H5TOOLS_DEBUG("[%d]hs_size1:%ld - hs_block1:%ld - hs_stride1:%ld", i - 1,
|
|
hs_size1[i - 1], hs_block1[i - 1], hs_stride1[i - 1]);
|
|
if (hs_size1[i - 1] >= hs_block1[i - 1]) {
|
|
hs_offset1[i - 1] += hs_size1[i - 1];
|
|
}
|
|
else {
|
|
hs_offset1[i - 1] += hs_stride1[i - 1];
|
|
}
|
|
}
|
|
else
|
|
hs_offset1[i - 1] += hs_size1[i - 1];
|
|
H5TOOLS_DEBUG("[%d]hs_offset1:%ld - opts->dims:%ld", i - 1, hs_offset1[i - 1],
|
|
opts->dims[i - 1]);
|
|
if (hs_offset1[i - 1] >= opts->dims[i - 1])
|
|
hs_offset1[i - 1] = 0;
|
|
else
|
|
carry = 0;
|
|
H5TOOLS_DEBUG("[%d]hs_offset1:%ld", i - 1, hs_offset1[i - 1]);
|
|
if (opts->sset[1] != NULL) {
|
|
H5TOOLS_DEBUG("[%d]hs_size2:%ld - hs_block2:%ld - hs_stride2:%ld", i - 1,
|
|
hs_size2[i - 1], hs_block2[i - 1], hs_stride2[i - 1]);
|
|
if (hs_size2[i - 1] >= hs_block2[i - 1]) {
|
|
hs_offset2[i - 1] += hs_size2[i - 1];
|
|
}
|
|
else {
|
|
hs_offset2[i - 1] += hs_stride2[i - 1];
|
|
}
|
|
}
|
|
else
|
|
hs_offset2[i - 1] += hs_size2[i - 1];
|
|
H5TOOLS_DEBUG("[%d]hs_offset2:%ld - opts->dims:%ld", i - 1, hs_offset2[i - 1],
|
|
opts->dims[i - 1]);
|
|
if (hs_offset2[i - 1] >= opts->dims[i - 1])
|
|
hs_offset2[i - 1] = 0;
|
|
H5TOOLS_DEBUG("[%d]hs_offset2:%ld", i - 1, hs_offset2[i - 1]);
|
|
}
|
|
} /* elmtno for loop */
|
|
} /* hyperslab read */
|
|
H5TOOLS_DEBUG("can compare complete");
|
|
} /*can_compare*/
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* close
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
done:
|
|
opts->err_stat = opts->err_stat | ret_value;
|
|
|
|
H5TOOLS_DEBUG("free names - errstat:%d", opts->err_stat);
|
|
/* free */
|
|
if (opts->obj_name[0] != NULL)
|
|
HDfree(opts->obj_name[0]);
|
|
opts->obj_name[0] = NULL;
|
|
if (opts->obj_name[1] != NULL)
|
|
HDfree(opts->obj_name[1]);
|
|
opts->obj_name[1] = NULL;
|
|
|
|
H5TOOLS_DEBUG("reclaim any VL memory");
|
|
if (buf1 != NULL) {
|
|
/* reclaim any VL memory, if necessary */
|
|
if (vl_data1)
|
|
H5Treclaim(m_tid1, sid1, H5P_DEFAULT, buf1);
|
|
HDfree(buf1);
|
|
buf1 = NULL;
|
|
}
|
|
if (buf2 != NULL) {
|
|
/* reclaim any VL memory, if necessary */
|
|
if (vl_data2)
|
|
H5Treclaim(m_tid2, sid2, H5P_DEFAULT, buf2);
|
|
HDfree(buf2);
|
|
buf2 = NULL;
|
|
}
|
|
H5TOOLS_DEBUG("reclaim any stripmine VL memory");
|
|
if (sm_buf1 != NULL) {
|
|
/* reclaim any VL memory, if necessary */
|
|
if (vl_data1)
|
|
H5Treclaim(m_tid1, sm_space1, H5P_DEFAULT, sm_buf1);
|
|
HDfree(sm_buf1);
|
|
sm_buf1 = NULL;
|
|
}
|
|
if (sm_buf2 != NULL) {
|
|
/* reclaim any VL memory, if necessary */
|
|
if (vl_data2)
|
|
H5Treclaim(m_tid2, sm_space2, H5P_DEFAULT, sm_buf2);
|
|
HDfree(sm_buf2);
|
|
sm_buf2 = NULL;
|
|
}
|
|
|
|
H5TOOLS_DEBUG("close ids");
|
|
/* disable error reporting */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Sclose(sid1);
|
|
H5Sclose(sid2);
|
|
H5Sclose(sm_space1);
|
|
H5Sclose(sm_space2);
|
|
H5Pclose(dcpl1);
|
|
H5Pclose(dcpl2);
|
|
H5Tclose(f_tid1);
|
|
H5Tclose(f_tid2);
|
|
H5Tclose(m_tid1);
|
|
H5Tclose(m_tid2);
|
|
/* enable error reporting */
|
|
}
|
|
H5E_END_TRY;
|
|
|
|
H5TOOLS_ENDDEBUG(": %d with nfound:%d", ret_value, nfound);
|
|
return nfound;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: diff_can_type
|
|
*
|
|
* Purpose: check for comparable TYPE and SPACE
|
|
*
|
|
* Return:
|
|
* 1, can compare
|
|
* 0, cannot compare
|
|
* -1, error
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
int
|
|
diff_can_type(hid_t f_tid1, hid_t f_tid2, int rank1, int rank2, hsize_t *dims1, hsize_t *dims2,
|
|
hsize_t *maxdim1, hsize_t *maxdim2, diff_opt_t *opts, int is_compound)
|
|
{
|
|
H5T_class_t tclass1;
|
|
H5T_class_t tclass2;
|
|
int maxdim_diff = 0; /* maximum dimensions are different */
|
|
int dim_diff = 0; /* current dimensions are different */
|
|
int i;
|
|
int ret_value = 1;
|
|
|
|
H5TOOLS_START_DEBUG(" ");
|
|
/*-------------------------------------------------------------------------
|
|
* check for the same class
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
if ((tclass1 = H5Tget_class(f_tid1)) < 0)
|
|
H5TOOLS_GOTO_ERROR(FAIL, "H5Tget_class first object failed");
|
|
if ((tclass2 = H5Tget_class(f_tid2)) < 0)
|
|
H5TOOLS_GOTO_ERROR(FAIL, "H5Tget_class second object failed");
|
|
|
|
H5TOOLS_DEBUG("obj_names: %s - %s", opts->obj_name[0], opts->obj_name[1]);
|
|
if (tclass1 != tclass2) {
|
|
if ((opts->mode_verbose || opts->mode_list_not_cmp) && opts->obj_name[0] && opts->obj_name[1]) {
|
|
if (is_compound) {
|
|
parallel_print("Not comparable: <%s> has a class %s and <%s> has a class %s\n",
|
|
opts->obj_name[0], get_class(tclass1), opts->obj_name[1], get_class(tclass2));
|
|
}
|
|
else {
|
|
parallel_print("Not comparable: <%s> is of class %s and <%s> is of class %s\n",
|
|
opts->obj_name[0], get_class(tclass1), opts->obj_name[1], get_class(tclass2));
|
|
}
|
|
}
|
|
|
|
opts->not_cmp = 1;
|
|
H5TOOLS_GOTO_DONE(0);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* check for non supported classes
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
switch (tclass1) {
|
|
case H5T_TIME:
|
|
if ((opts->mode_verbose || opts->mode_list_not_cmp) && opts->obj_name[0] && opts->obj_name[1]) {
|
|
parallel_print("Not comparable: <%s> and <%s> are of class %s\n", opts->obj_name[0],
|
|
opts->obj_name[1], get_class(tclass2));
|
|
} /* end if */
|
|
|
|
opts->not_cmp = 1;
|
|
H5TOOLS_GOTO_DONE(0);
|
|
break;
|
|
|
|
case H5T_INTEGER:
|
|
case H5T_FLOAT:
|
|
case H5T_COMPOUND:
|
|
case H5T_STRING:
|
|
case H5T_ARRAY:
|
|
case H5T_BITFIELD:
|
|
case H5T_OPAQUE:
|
|
case H5T_ENUM:
|
|
case H5T_VLEN:
|
|
case H5T_REFERENCE:
|
|
case H5T_NO_CLASS:
|
|
case H5T_NCLASSES:
|
|
default:
|
|
H5TOOLS_DEBUG("class - %s", get_class(tclass1));
|
|
break;
|
|
} /* end switch */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* check for equal file datatype; warning only
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
if ((H5Tequal(f_tid1, f_tid2) == 0) && (opts->mode_verbose) && opts->obj_name[0] && opts->obj_name[1]) {
|
|
H5T_class_t cl = H5Tget_class(f_tid1);
|
|
|
|
parallel_print("Warning: different storage datatype\n");
|
|
if (cl == H5T_INTEGER || cl == H5T_FLOAT) {
|
|
parallel_print("<%s> has file datatype ", opts->obj_name[0]);
|
|
print_type(f_tid1);
|
|
parallel_print("\n");
|
|
parallel_print("<%s> has file datatype ", opts->obj_name[1]);
|
|
print_type(f_tid2);
|
|
parallel_print("\n");
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* check for the same rank
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
if (rank1 != rank2) {
|
|
if ((opts->mode_verbose || opts->mode_list_not_cmp) && opts->obj_name[0] && opts->obj_name[1]) {
|
|
parallel_print("Not comparable: <%s> has rank %d, dimensions ", opts->obj_name[0], rank1);
|
|
print_dimensions(rank1, dims1);
|
|
parallel_print(", max dimensions ");
|
|
print_dimensions(rank1, maxdim1);
|
|
parallel_print("\n");
|
|
parallel_print("and <%s> has rank %d, dimensions ", opts->obj_name[1], rank2);
|
|
print_dimensions(rank2, dims2);
|
|
parallel_print(", max dimensions ");
|
|
print_dimensions(rank2, maxdim2);
|
|
parallel_print("\n");
|
|
}
|
|
|
|
opts->not_cmp = 1;
|
|
H5TOOLS_GOTO_DONE(0);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* check for different dimensions
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
for (i = 0; i < rank1; i++) {
|
|
if (maxdim1 && maxdim2) {
|
|
if (maxdim1[i] != maxdim2[i])
|
|
maxdim_diff = 1;
|
|
}
|
|
if (dims1[i] != dims2[i])
|
|
dim_diff = 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* current dimensions
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
if (dim_diff == 1) {
|
|
if ((opts->mode_verbose || opts->mode_list_not_cmp) && opts->obj_name[0] && opts->obj_name[1]) {
|
|
parallel_print("Not comparable: <%s> has rank %d, dimensions ", opts->obj_name[0], rank1);
|
|
print_dimensions(rank1, dims1);
|
|
if (maxdim1 && maxdim2) {
|
|
parallel_print(", max dimensions ");
|
|
print_dimensions(rank1, maxdim1);
|
|
parallel_print("\n");
|
|
parallel_print("and <%s> has rank %d, dimensions ", opts->obj_name[1], rank2);
|
|
print_dimensions(rank2, dims2);
|
|
parallel_print(", max dimensions ");
|
|
print_dimensions(rank2, maxdim2);
|
|
parallel_print("\n");
|
|
}
|
|
}
|
|
|
|
opts->not_cmp = 1;
|
|
H5TOOLS_GOTO_DONE(0);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* maximum dimensions; just give a warning
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
if (maxdim1 && maxdim2 && maxdim_diff == 1 && opts->obj_name[0]) {
|
|
if (opts->mode_verbose) {
|
|
parallel_print("Warning: different maximum dimensions\n");
|
|
parallel_print("<%s> has max dimensions ", opts->obj_name[0]);
|
|
print_dimensions(rank1, maxdim1);
|
|
parallel_print("\n");
|
|
parallel_print("<%s> has max dimensions ", opts->obj_name[1]);
|
|
print_dimensions(rank2, maxdim2);
|
|
parallel_print("\n");
|
|
}
|
|
}
|
|
|
|
if (tclass1 == H5T_STRING) {
|
|
htri_t vstrtype1 = -1;
|
|
htri_t vstrtype2 = -1;
|
|
H5TOOLS_DEBUG(" - H5T_STRING");
|
|
|
|
vstrtype1 = H5Tis_variable_str(f_tid1);
|
|
vstrtype2 = H5Tis_variable_str(f_tid2);
|
|
|
|
/* no compare if either one but not both are variable string type */
|
|
if (vstrtype1 != vstrtype2) {
|
|
if ((opts->mode_verbose || opts->mode_list_not_cmp) && opts->obj_name[0] && opts->obj_name[1])
|
|
parallel_print("Not comparable: <%s> or <%s> is of mixed string type\n", opts->obj_name[0],
|
|
opts->obj_name[1]);
|
|
|
|
opts->not_cmp = 1;
|
|
H5TOOLS_GOTO_DONE(0);
|
|
}
|
|
}
|
|
|
|
if (tclass1 == H5T_COMPOUND) {
|
|
int nmembs1;
|
|
int nmembs2;
|
|
int j;
|
|
hid_t memb_type1 = H5I_INVALID_HID;
|
|
hid_t memb_type2 = H5I_INVALID_HID;
|
|
H5TOOLS_DEBUG(" - H5T_COMPOUND");
|
|
|
|
nmembs1 = H5Tget_nmembers(f_tid1);
|
|
nmembs2 = H5Tget_nmembers(f_tid2);
|
|
|
|
if (nmembs1 != nmembs2) {
|
|
if ((opts->mode_verbose || opts->mode_list_not_cmp) && opts->obj_name[0] && opts->obj_name[1]) {
|
|
parallel_print("Not comparable: <%s> has %d members ", opts->obj_name[0], nmembs1);
|
|
parallel_print("<%s> has %d members ", opts->obj_name[1], nmembs2);
|
|
parallel_print("\n");
|
|
}
|
|
|
|
opts->not_cmp = 1;
|
|
H5TOOLS_GOTO_DONE(0);
|
|
}
|
|
|
|
for (j = 0; j < nmembs1; j++) {
|
|
memb_type1 = H5Tget_member_type(f_tid1, (unsigned)j);
|
|
memb_type2 = H5Tget_member_type(f_tid2, (unsigned)j);
|
|
|
|
if (diff_can_type(memb_type1, memb_type2, rank1, rank2, dims1, dims2, maxdim1, maxdim2, opts,
|
|
1) != 1) {
|
|
opts->not_cmp = 1;
|
|
H5Tclose(memb_type1);
|
|
H5Tclose(memb_type2);
|
|
H5TOOLS_GOTO_DONE(0);
|
|
}
|
|
H5Tclose(memb_type1);
|
|
H5Tclose(memb_type2);
|
|
}
|
|
}
|
|
done:
|
|
if (ret_value < 0)
|
|
opts->err_stat = H5DIFF_ERR;
|
|
|
|
H5TOOLS_ENDDEBUG(" - %d", ret_value);
|
|
return ret_value;
|
|
}
|
|
|
|
#if defined(H5DIFF_DEBUG_UNUSED)
|
|
/* this function is not currently used, but could be useful */
|
|
/*-------------------------------------------------------------------------
|
|
* Function: print_sizes
|
|
*
|
|
* Purpose: Print datatype sizes
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
void print_sizes(const char *obj1, const char *obj2, hid_t f_tid1, hid_t f_tid2, hid_t m_tid1, hid_t m_tid2);
|
|
|
|
void
|
|
print_sizes(const char *obj1, const char *obj2, hid_t f_tid1, hid_t f_tid2, hid_t m_tid1, hid_t m_tid2)
|
|
{
|
|
size_t f_size1, f_size2; /* size of type in file */
|
|
size_t m_size1, m_size2; /* size of type in memory */
|
|
|
|
f_size1 = H5Tget_size(f_tid1);
|
|
f_size2 = H5Tget_size(f_tid2);
|
|
m_size1 = H5Tget_size(m_tid1);
|
|
m_size2 = H5Tget_size(m_tid2);
|
|
|
|
parallel_print("\n");
|
|
parallel_print("------------------\n");
|
|
parallel_print("sizeof(char) %u\n", sizeof(char));
|
|
parallel_print("sizeof(short) %u\n", sizeof(short));
|
|
parallel_print("sizeof(int) %u\n", sizeof(int));
|
|
parallel_print("sizeof(long) %u\n", sizeof(long));
|
|
parallel_print("<%s> ------------------\n", obj1);
|
|
parallel_print("type on file ");
|
|
print_type(f_tid1);
|
|
parallel_print("\n");
|
|
parallel_print("size on file %u\n", f_size1);
|
|
|
|
parallel_print("type on memory ");
|
|
print_type(m_tid1);
|
|
parallel_print("\n");
|
|
parallel_print("size on memory %u\n", m_size1);
|
|
|
|
parallel_print("<%s> ------------------\n", obj2);
|
|
parallel_print("type on file ");
|
|
print_type(f_tid2);
|
|
parallel_print("\n");
|
|
parallel_print("size on file %u\n", f_size2);
|
|
|
|
parallel_print("type on memory ");
|
|
print_type(m_tid2);
|
|
parallel_print("\n");
|
|
parallel_print("size on memory %u\n", m_size2);
|
|
parallel_print("\n");
|
|
}
|
|
#endif /* H5DIFF_DEBUG */
|