Files
hdf5/tools/lib/h5diff_util.c
jhendersonHDF 90429f5e7d Implement support for complex number datatypes (#4630)
* Implement support for complex number datatypes

Adds the new datatype class H5T_COMPLEX

Adds the new API function H5Tcomplex_create which creates a complex
number datatype from an ID of a base floating-point datatype

Adds the new feature check macros H5_HAVE_COMPLEX_NUMBERS and
H5_HAVE_C99_COMPLEX_NUMBERS

Adds the new datatype size macros H5_SIZEOF_FLOAT_COMPLEX,
H5_SIZEOF_DOUBLE_COMPLEX and H5_SIZEOF_LONG_DOUBLE_COMPLEX

Adds the new datatype ID macros H5T_NATIVE_FLOAT_COMPLEX,
H5T_NATIVE_DOUBLE_COMPLEX, H5T_NATIVE_LDOUBLE_COMPLEX,
H5T_CPLX_IEEE_F16LE, H5T_CPLX_IEEE_F16BE,
H5T_CPLX_IEEE_F32LE, H5T_CPLX_IEEE_F32BE,
H5T_CPLX_IEEE_F64LE and H5T_CPLX_IEEE_F64BE

Adds hard and soft datatype conversion paths between complex number
datatypes and all the integer and floating-point datatypes, as well as
between other complex number datatypes

Adds a special conversion path between complex number datatypes and
array or compound datatypes where the in-memory layout of data is the
same between the datatypes and data can be converted directly

Adds support for complex number datatypes to the h5dump, h5ls and
h5diff/ph5diff tools. Allows h5dump '-m' option to change floating-point
printing format for float complex and double complex datatypes, as well
as long double complex if it has the same size as double complex

Adds minimal support to the h5watch and h5import tools

Adds support for the predefined complex number datatypes and
H5Tcomplex_create function to the Java wrappers. Also adds initial,
untested support to the JNI for future use with HDFView

Adds support for just the H5T_COMPLEX datatype class to the Fortran
wrappers

Adds support for the predefined complex number datatypes and
H5Tcomplex_create function to the high level library H5LT interface
for use with the H5LTtext_to_dtype and H5LTdtype_to_text functions

Changes some usages of "complex" in the library since it conflicts with
the "complex" keyword from the complex.h header. Also changes various
usages of the word "complex" throughout the library to distinguish
compound datatypes from complex datatypes.
2024-10-31 13:54:25 -07:00

377 lines
12 KiB
C

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* 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 LICENSE 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"
/* global variables */
int g_nTasks = 1;
/*-------------------------------------------------------------------------
* Function: print_dimensions
*
* Purpose: print dimensions
*-------------------------------------------------------------------------
*/
void
print_dimensions(int rank, hsize_t *dims)
{
int i;
if (rank <= 0)
parallel_print("H5S_SCALAR");
else {
if (!dims)
parallel_print("dimension is NULL");
else {
parallel_print("[");
for (i = 0; i < rank - 1; i++) {
parallel_print("%" PRIuHSIZE, dims[i]);
parallel_print("x");
}
parallel_print("%" PRIuHSIZE, dims[rank - 1]);
parallel_print("]");
}
}
}
/*-------------------------------------------------------------------------
* Function: print_type
*
* Purpose: Print name of datatype
*
* Return: void
*
* Comments: Adapted from h5dump for H5T_INTEGER and H5T_FLOAT classes only
*-------------------------------------------------------------------------
*/
void
print_type(hid_t type)
{
switch (H5Tget_class(type)) {
case H5T_INTEGER:
if (H5Tequal(type, H5T_STD_I8BE))
parallel_print("H5T_STD_I8BE");
else if (H5Tequal(type, H5T_STD_I8LE))
parallel_print("H5T_STD_I8LE");
else if (H5Tequal(type, H5T_STD_I16BE))
parallel_print("H5T_STD_I16BE");
else if (H5Tequal(type, H5T_STD_I16LE))
parallel_print("H5T_STD_I16LE");
else if (H5Tequal(type, H5T_STD_I32BE))
parallel_print("H5T_STD_I32BE");
else if (H5Tequal(type, H5T_STD_I32LE))
parallel_print("H5T_STD_I32LE");
else if (H5Tequal(type, H5T_STD_I64BE))
parallel_print("H5T_STD_I64BE");
else if (H5Tequal(type, H5T_STD_I64LE))
parallel_print("H5T_STD_I64LE");
else if (H5Tequal(type, H5T_STD_U8BE))
parallel_print("H5T_STD_U8BE");
else if (H5Tequal(type, H5T_STD_U8LE))
parallel_print("H5T_STD_U8LE");
else if (H5Tequal(type, H5T_STD_U16BE))
parallel_print("H5T_STD_U16BE");
else if (H5Tequal(type, H5T_STD_U16LE))
parallel_print("H5T_STD_U16LE");
else if (H5Tequal(type, H5T_STD_U32BE))
parallel_print("H5T_STD_U32BE");
else if (H5Tequal(type, H5T_STD_U32LE))
parallel_print("H5T_STD_U32LE");
else if (H5Tequal(type, H5T_STD_U64BE))
parallel_print("H5T_STD_U64BE");
else if (H5Tequal(type, H5T_STD_U64LE))
parallel_print("H5T_STD_U64LE");
else if (H5Tequal(type, H5T_NATIVE_SCHAR))
parallel_print("H5T_NATIVE_SCHAR");
else if (H5Tequal(type, H5T_NATIVE_UCHAR))
parallel_print("H5T_NATIVE_UCHAR");
else if (H5Tequal(type, H5T_NATIVE_SHORT))
parallel_print("H5T_NATIVE_SHORT");
else if (H5Tequal(type, H5T_NATIVE_USHORT))
parallel_print("H5T_NATIVE_USHORT");
else if (H5Tequal(type, H5T_NATIVE_INT))
parallel_print("H5T_NATIVE_INT");
else if (H5Tequal(type, H5T_NATIVE_UINT))
parallel_print("H5T_NATIVE_UINT");
else if (H5Tequal(type, H5T_NATIVE_LONG))
parallel_print("H5T_NATIVE_LONG");
else if (H5Tequal(type, H5T_NATIVE_ULONG))
parallel_print("H5T_NATIVE_ULONG");
else if (H5Tequal(type, H5T_NATIVE_LLONG))
parallel_print("H5T_NATIVE_LLONG");
else if (H5Tequal(type, H5T_NATIVE_ULLONG))
parallel_print("H5T_NATIVE_ULLONG");
else
parallel_print("undefined integer");
break;
case H5T_FLOAT:
if (H5Tequal(type, H5T_IEEE_F16BE))
parallel_print("H5T_IEEE_F16BE");
else if (H5Tequal(type, H5T_IEEE_F16LE))
parallel_print("H5T_IEEE_F16LE");
else if (H5Tequal(type, H5T_IEEE_F32BE))
parallel_print("H5T_IEEE_F32BE");
else if (H5Tequal(type, H5T_IEEE_F32LE))
parallel_print("H5T_IEEE_F32LE");
else if (H5Tequal(type, H5T_IEEE_F64BE))
parallel_print("H5T_IEEE_F64BE");
else if (H5Tequal(type, H5T_IEEE_F64LE))
parallel_print("H5T_IEEE_F64LE");
#ifdef H5_HAVE__FLOAT16
else if (H5Tequal(type, H5T_NATIVE_FLOAT16))
parallel_print("H5T_NATIVE_FLOAT16");
#endif
else if (H5Tequal(type, H5T_NATIVE_FLOAT))
parallel_print("H5T_NATIVE_FLOAT");
else if (H5Tequal(type, H5T_NATIVE_DOUBLE))
parallel_print("H5T_NATIVE_DOUBLE");
else if (H5Tequal(type, H5T_NATIVE_LDOUBLE))
parallel_print("H5T_NATIVE_LDOUBLE");
else
parallel_print("undefined float");
break;
case H5T_BITFIELD:
if (H5Tequal(type, H5T_STD_B8BE))
parallel_print("H5T_STD_B8BE");
else if (H5Tequal(type, H5T_STD_B8LE))
parallel_print("H5T_STD_B8LE");
else if (H5Tequal(type, H5T_STD_B16BE))
parallel_print("H5T_STD_B16BE");
else if (H5Tequal(type, H5T_STD_B16LE))
parallel_print("H5T_STD_B16LE");
else if (H5Tequal(type, H5T_STD_B32BE))
parallel_print("H5T_STD_B32BE");
else if (H5Tequal(type, H5T_STD_B32LE))
parallel_print("H5T_STD_B32LE");
else if (H5Tequal(type, H5T_STD_B64BE))
parallel_print("H5T_STD_B64BE");
else if (H5Tequal(type, H5T_STD_B64LE))
parallel_print("H5T_STD_B64LE");
else
parallel_print("undefined bitfield");
break;
case H5T_TIME:
case H5T_STRING:
case H5T_OPAQUE:
case H5T_COMPOUND:
case H5T_REFERENCE:
case H5T_ENUM:
case H5T_VLEN:
case H5T_ARRAY:
case H5T_COMPLEX:
case H5T_NO_CLASS:
case H5T_NCLASSES:
default:
return;
} /* end switch */
}
/*-------------------------------------------------------------------------
* Function: diff_basename
*
* Purpose: Returns a pointer to the last component absolute name
*-------------------------------------------------------------------------
*/
H5_ATTR_PURE const char *
diff_basename(const char *name)
{
size_t i;
if (name == NULL)
return NULL;
/* Find the end of the base name */
i = strlen(name);
while (i > 0 && '/' == name[i - 1])
--i;
/* Skip backward over base name */
while (i > 0 && '/' != name[i - 1])
--i;
return (name + i);
}
/*-------------------------------------------------------------------------
* Function: get_type
*
* Purpose: Returns the type as a string
*-------------------------------------------------------------------------
*/
H5_ATTR_CONST const char *
get_type(h5trav_type_t type)
{
switch (type) {
case H5TRAV_TYPE_DATASET:
return ("H5G_DATASET");
case H5TRAV_TYPE_GROUP:
return ("H5G_GROUP");
case H5TRAV_TYPE_NAMED_DATATYPE:
return ("H5G_TYPE");
case H5TRAV_TYPE_LINK:
return ("H5G_LINK");
case H5TRAV_TYPE_UDLINK:
return ("H5G_UDLINK");
case H5TRAV_TYPE_UNKNOWN:
default:
return ("unknown type");
}
}
/*-------------------------------------------------------------------------
* Function: get_sign
*
* Purpose: Returns the sign as a string
*-------------------------------------------------------------------------
*/
H5_ATTR_CONST const char *
get_sign(H5T_sign_t sign)
{
switch (sign) {
case H5T_SGN_NONE:
return "H5T_SGN_NONE";
case H5T_SGN_2:
return "H5T_SGN_2";
case H5T_SGN_ERROR:
return "H5T_SGN_ERROR";
case H5T_NSGN:
return "H5T_NSGN";
default:
return "unknown sign value";
} /* end switch */
}
/*-------------------------------------------------------------------------
* Function: get_class
*
* Purpose: Returns the class as a string
*-------------------------------------------------------------------------
*/
H5_ATTR_CONST const char *
get_class(H5T_class_t tclass)
{
switch (tclass) {
case H5T_TIME:
return ("H5T_TIME");
case H5T_INTEGER:
return ("H5T_INTEGER");
case H5T_FLOAT:
return ("H5T_FLOAT");
case H5T_STRING:
return ("H5T_STRING");
case H5T_BITFIELD:
return ("H5T_BITFIELD");
case H5T_OPAQUE:
return ("H5T_OPAQUE");
case H5T_COMPOUND:
return ("H5T_COMPOUND");
case H5T_REFERENCE:
return ("H5T_REFERENCE");
case H5T_ENUM:
return ("H5T_ENUM");
case H5T_VLEN:
return ("H5T_VLEN");
case H5T_ARRAY:
return ("H5T_ARRAY");
case H5T_COMPLEX:
return ("H5T_COMPLEX");
case H5T_NO_CLASS:
case H5T_NCLASSES:
default:
return ("Invalid class");
} /* end switch */
} /* end get_class() */
/*-------------------------------------------------------------------------
* Function: print_found
*
* Purpose: print number of differences found
*-------------------------------------------------------------------------
*/
void
print_found(hsize_t nfound)
{
if (g_Parallel)
parallel_print("%" PRIuHSIZE " differences found\n", nfound);
else
fprintf(stdout, "%" PRIuHSIZE " differences found\n", nfound);
}
/*-----------------------------------------------------------------
* Function: match_up_memsize
*
* Purpose: match smaller memory size up to bigger memory size
*------------------------------------------------------------------
*/
herr_t
match_up_memsize(hid_t f_tid1_id, hid_t f_tid2_id, hid_t *m_tid1, hid_t *m_tid2, size_t *m_size1,
size_t *m_size2)
{
herr_t ret_value = SUCCEED;
H5TOOLS_START_DEBUG(" ");
if ((*m_size1) != (*m_size2)) {
if ((*m_size1) < (*m_size2)) {
H5Tclose(*m_tid1);
if (((*m_tid1) = H5Tget_native_type(f_tid2_id, H5T_DIR_DEFAULT)) < 0)
H5TOOLS_GOTO_ERROR(FAIL, "H5Tget_native_type failed");
*m_size1 = H5Tget_size(*m_tid1);
} /* end if */
else {
H5Tclose(*m_tid2);
if (((*m_tid2) = H5Tget_native_type(f_tid1_id, H5T_DIR_DEFAULT)) < 0)
H5TOOLS_GOTO_ERROR(FAIL, "H5Tget_native_type failed");
*m_size2 = H5Tget_size(*m_tid2);
} /* end else */
} /* end if */
if ((*m_size1) != (*m_size2))
H5TOOLS_GOTO_ERROR(FAIL, "native type sizes do not compare");
done:
H5TOOLS_ENDDEBUG(" ");
return ret_value;
}