mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-09-25 04:09:44 +03:00
Add predefined datatype for FP4 format (#6122)
Adds predefined datatype for FP4 data in E2M1 format Does not add support for any native FP4 types; datatype conversions are performed in software
This commit is contained in:
@@ -1219,8 +1219,8 @@ test_create_dataset_predefined_types(void H5_ATTR_UNUSED *params)
|
||||
H5T_IEEE_F16LE, H5T_IEEE_F16BE, H5T_IEEE_F32LE, H5T_IEEE_F32BE,
|
||||
H5T_IEEE_F64LE, H5T_IEEE_F64BE, H5T_FLOAT_BFLOAT16LE, H5T_FLOAT_BFLOAT16BE,
|
||||
H5T_FLOAT_F8E4M3, H5T_FLOAT_F8E5M2, H5T_FLOAT_F6E2M3, H5T_FLOAT_F6E3M2,
|
||||
H5T_COMPLEX_IEEE_F16BE, H5T_COMPLEX_IEEE_F16LE, H5T_COMPLEX_IEEE_F32BE, H5T_COMPLEX_IEEE_F32LE,
|
||||
H5T_COMPLEX_IEEE_F64BE, H5T_COMPLEX_IEEE_F64LE};
|
||||
H5T_FLOAT_F4E2M1, H5T_COMPLEX_IEEE_F16BE, H5T_COMPLEX_IEEE_F16LE, H5T_COMPLEX_IEEE_F32BE,
|
||||
H5T_COMPLEX_IEEE_F32LE, H5T_COMPLEX_IEEE_F64BE, H5T_COMPLEX_IEEE_F64LE};
|
||||
|
||||
TESTING("dataset creation with predefined datatypes");
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
/* The number of predefined floating point types in HDF5
|
||||
*/
|
||||
#define NUM_PREDEFINED_FLOAT_TYPES 12
|
||||
#define NUM_PREDEFINED_FLOAT_TYPES 13
|
||||
|
||||
/* The number of predefined complex number types in HDF5
|
||||
*/
|
||||
@@ -339,6 +339,9 @@ generate_random_datatype_float(H5T_class_t H5_ATTR_UNUSED parent_class, bool H5_
|
||||
case 11:
|
||||
type_to_copy = H5T_FLOAT_F6E3M2;
|
||||
break;
|
||||
case 12:
|
||||
type_to_copy = H5T_FLOAT_F4E2M1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf(" invalid value for floating point type; should not happen\n");
|
||||
|
||||
+267
-4
@@ -74,10 +74,10 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static const char *FILENAME[] = {"dtypes0", "dtypes1", "dtypes2", "dtypes3", "dtypes4",
|
||||
"dtypes5", "dtypes6", "dtypes7", "dtypes8", "dtypes9",
|
||||
"dtypes10", "dtypes11", "dtypes12", "dtypes13", "dtypes14",
|
||||
"dtypes15", "dtypes16", "dtypes17", "dtypes18", NULL};
|
||||
static const char *FILENAME[] = {"dtypes0", "dtypes1", "dtypes2", "dtypes3", "dtypes4", "dtypes5",
|
||||
"dtypes6", "dtypes7", "dtypes8", "dtypes9", "dtypes10", "dtypes11",
|
||||
"dtypes12", "dtypes13", "dtypes14", "dtypes15", "dtypes16", "dtypes17",
|
||||
"dtypes18", "dtypes19", NULL};
|
||||
|
||||
#define TESTFILE "bad_compound.h5"
|
||||
|
||||
@@ -8007,6 +8007,268 @@ error:
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_fp4
|
||||
*
|
||||
* Purpose: Tests the FP4 datatype.
|
||||
*
|
||||
* Return: Success: 0
|
||||
* Failure: number of errors
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
test_fp4(void)
|
||||
{
|
||||
H5T_class_t type_class;
|
||||
H5T_order_t type_order;
|
||||
H5T_norm_t type_norm;
|
||||
H5T_pad_t lsb_pad;
|
||||
H5T_pad_t msb_pad;
|
||||
H5T_pad_t inpad;
|
||||
hsize_t dims[1];
|
||||
size_t type_size;
|
||||
size_t type_prec;
|
||||
size_t sign_pos;
|
||||
size_t expo_pos;
|
||||
size_t mant_pos;
|
||||
size_t expo_size;
|
||||
size_t mant_size;
|
||||
size_t expo_bias;
|
||||
hid_t fid = H5I_INVALID_HID;
|
||||
hid_t space_id = H5I_INVALID_HID;
|
||||
hid_t dset_id = H5I_INVALID_HID;
|
||||
hid_t dcpl_id = H5I_INVALID_HID;
|
||||
char filename[256] = {0};
|
||||
int type_offset;
|
||||
|
||||
TESTING("FP4 datatypes");
|
||||
|
||||
/* Check characteristics of the predefined type */
|
||||
|
||||
if ((type_class = H5Tget_class(H5T_FLOAT_F4E2M1)) < 0) {
|
||||
H5_FAILED();
|
||||
printf("Couldn't get datatype class for H5T_FLOAT_F4E2M1\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (H5T_FLOAT != type_class) {
|
||||
H5_FAILED();
|
||||
printf("Datatype class for H5T_FLOAT_F4E2M1 wasn't H5T_FLOAT\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((type_size = H5Tget_size(H5T_FLOAT_F4E2M1)) == 0) {
|
||||
H5_FAILED();
|
||||
printf("Couldn't get datatype size for H5T_FLOAT_F4E2M1\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (type_size != 1) {
|
||||
H5_FAILED();
|
||||
printf("Datatype size for H5T_FLOAT_F4E2M1 was incorrect (expected 1, got %zu)\n", type_size);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((type_order = H5Tget_order(H5T_FLOAT_F4E2M1)) < 0) {
|
||||
H5_FAILED();
|
||||
printf("Couldn't get datatype order for H5T_FLOAT_F4E2M1\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (type_order != H5T_ORDER_LE) {
|
||||
H5_FAILED();
|
||||
printf("Datatype order for H5T_FLOAT_F4E2M1 wasn't H5T_ORDER_LE\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((type_prec = H5Tget_precision(H5T_FLOAT_F4E2M1)) == 0) {
|
||||
H5_FAILED();
|
||||
printf("Couldn't get datatype precision for H5T_FLOAT_F4E2M1\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (type_prec != 4) {
|
||||
H5_FAILED();
|
||||
printf("Datatype precision for H5T_FLOAT_F4E2M1 was incorrect (expected 4, got %zu)\n", type_prec);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((type_offset = H5Tget_offset(H5T_FLOAT_F4E2M1)) < 0) {
|
||||
H5_FAILED();
|
||||
printf("Couldn't get datatype offset for H5T_FLOAT_F4E2M1\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (type_offset != 0) {
|
||||
H5_FAILED();
|
||||
printf("Datatype offset for H5T_FLOAT_F4E2M1 was incorrect (expected 0, got %d)\n", type_offset);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (H5Tget_pad(H5T_FLOAT_F4E2M1, &lsb_pad, &msb_pad) < 0) {
|
||||
H5_FAILED();
|
||||
printf("Couldn't get datatype padding type for H5T_FLOAT_F4E2M1\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (lsb_pad != H5T_PAD_ZERO || msb_pad != H5T_PAD_ZERO) {
|
||||
H5_FAILED();
|
||||
printf("Datatype padding type for H5T_FLOAT_F4E2M1 was incorrect (expected H5T_PAD_ZERO, got lsb pad "
|
||||
"type %d, msb pad type %d)\n",
|
||||
lsb_pad, msb_pad);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (H5Tget_fields(H5T_FLOAT_F4E2M1, &sign_pos, &expo_pos, &expo_size, &mant_pos, &mant_size) < 0) {
|
||||
H5_FAILED();
|
||||
printf("Couldn't get floating-point bit field information for H5T_FLOAT_F4E2M1\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (sign_pos != 3 || expo_pos != 1 || mant_pos != 0 || expo_size != 2 || mant_size != 1) {
|
||||
H5_FAILED();
|
||||
printf("H5T_FLOAT_F4E2M1 didn't match FP4 E2M1 specification "
|
||||
"(expected spos=3, epos=1, esize=2, mpos=0, msize=1, "
|
||||
"got spos=%zu, epos=%zu, esize=%zu, mpos=%zu, msize=%zu)\n",
|
||||
sign_pos, expo_pos, expo_size, mant_pos, mant_size);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((expo_bias = H5Tget_ebias(H5T_FLOAT_F4E2M1)) == 0) {
|
||||
H5_FAILED();
|
||||
printf("Couldn't get datatype exponent bias for H5T_FLOAT_F4E2M1\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (expo_bias != 1) {
|
||||
H5_FAILED();
|
||||
printf("Datatype exponent bias for H5T_FLOAT_F4E2M1 was incorrect (expected 1, got %zu)\n",
|
||||
expo_bias);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((type_norm = H5Tget_norm(H5T_FLOAT_F4E2M1)) < 0) {
|
||||
H5_FAILED();
|
||||
printf("Couldn't get datatype mantissa normalization type for H5T_FLOAT_F4E2M1\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (type_norm != H5T_NORM_IMPLIED) {
|
||||
H5_FAILED();
|
||||
printf("Datatype mantissa normalization type for H5T_FLOAT_F4E2M1 wasn't H5T_NORM_IMPLIED\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((inpad = H5Tget_inpad(H5T_FLOAT_F4E2M1)) < 0) {
|
||||
H5_FAILED();
|
||||
printf("Couldn't get datatype unused bits padding type for H5T_FLOAT_F4E2M1\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (inpad != H5T_PAD_ZERO) {
|
||||
H5_FAILED();
|
||||
printf("Datatype unused bits padding type for H5T_FLOAT_F4E2M1 was incorrect (expected H5T_PAD_ZERO, "
|
||||
"got pad type %d)\n",
|
||||
inpad);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that some random conversions on the FP4 datatype
|
||||
* are currently covered by general software routines rather
|
||||
* than compiler conversions.
|
||||
*/
|
||||
|
||||
if (H5Tcompiler_conv(H5T_FLOAT_F4E2M1, H5T_IEEE_F16LE) != false) {
|
||||
H5_FAILED();
|
||||
printf("Conversion path for H5T_FLOAT_F4E2M1 -> H5T_IEEE_F16LE was not a software conversion\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (H5Tcompiler_conv(H5T_FLOAT_F4E2M1, H5T_NATIVE_INT) != false) {
|
||||
H5_FAILED();
|
||||
printf("Conversion path for H5T_FLOAT_F4E2M1 -> H5T_NATIVE_INT was not a software conversion\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create datasets with the FP4 datatype and check the dataset raw data storage size
|
||||
*/
|
||||
h5_fixname(FILENAME[19], H5P_DEFAULT, filename, sizeof filename);
|
||||
|
||||
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
|
||||
H5_FAILED();
|
||||
AT();
|
||||
printf("Can't create file!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
dims[0] = 10000;
|
||||
if ((space_id = H5Screate_simple(1, dims, NULL)) < 0) {
|
||||
H5_FAILED();
|
||||
AT();
|
||||
printf("Can't create dataspace\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((dcpl_id = H5Pcreate(H5P_DATASET_CREATE)) < 0) {
|
||||
H5_FAILED();
|
||||
AT();
|
||||
printf("Can't create DCPL\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (H5Pset_alloc_time(dcpl_id, H5D_ALLOC_TIME_EARLY) < 0) {
|
||||
H5_FAILED();
|
||||
AT();
|
||||
printf("Can't set alloc time\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((dset_id = H5Dcreate2(fid, "DatasetE2M1", H5T_FLOAT_F4E2M1, space_id, H5P_DEFAULT, dcpl_id,
|
||||
H5P_DEFAULT)) < 0) {
|
||||
H5_FAILED();
|
||||
AT();
|
||||
printf("Can't create dataset\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (H5Dget_storage_size(dset_id) != dims[0] /* 1 byte datatype */) {
|
||||
H5_FAILED();
|
||||
AT();
|
||||
printf("Incorrect dataset raw data storage size allocated in file\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (H5Pclose(dcpl_id) < 0)
|
||||
TEST_ERROR;
|
||||
if (H5Sclose(space_id) < 0)
|
||||
TEST_ERROR;
|
||||
if (H5Dclose(dset_id) < 0)
|
||||
TEST_ERROR;
|
||||
if (H5Fclose(fid) < 0)
|
||||
TEST_ERROR;
|
||||
if (H5Fdelete(filename, H5P_DEFAULT) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
PASSED();
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY
|
||||
{
|
||||
H5Pclose(dcpl_id);
|
||||
H5Sclose(space_id);
|
||||
H5Dclose(dset_id);
|
||||
H5Fclose(fid);
|
||||
H5Fdelete(filename, H5P_DEFAULT);
|
||||
}
|
||||
H5E_END_TRY
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_complex_type
|
||||
*
|
||||
@@ -14209,6 +14471,7 @@ main(void)
|
||||
nerrors += test_bfloat16();
|
||||
nerrors += test_fp8();
|
||||
nerrors += test_fp6();
|
||||
nerrors += test_fp4();
|
||||
nerrors += test_complex_type();
|
||||
#ifdef H5_HAVE_COMPLEX_NUMBERS
|
||||
nerrors += test_complex_type_conv_funcs();
|
||||
|
||||
@@ -3380,6 +3380,62 @@ error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static herr_t
|
||||
test_fp4(void)
|
||||
{
|
||||
hid_t native_type = H5I_INVALID_HID;
|
||||
|
||||
TESTING("FP4 datatypes");
|
||||
|
||||
/*
|
||||
* Just ensure that the FP4 types are currently promoted
|
||||
* to either float16 or float, depending on whether float16
|
||||
* support is enabled. Until native support is added for a
|
||||
* FP4 type, conversion from FP4 to float16 should be fine.
|
||||
*/
|
||||
|
||||
if ((native_type = H5Tget_native_type(H5T_FLOAT_F4E2M1, H5T_DIR_ASCEND)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
#ifdef H5_HAVE__FLOAT16
|
||||
if (true != H5Tequal(native_type, H5T_NATIVE_FLOAT16))
|
||||
TEST_ERROR;
|
||||
#else
|
||||
if (true != H5Tequal(native_type, H5T_NATIVE_FLOAT))
|
||||
TEST_ERROR;
|
||||
#endif
|
||||
|
||||
if (H5Tclose(native_type) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
if ((native_type = H5Tget_native_type(H5T_FLOAT_F4E2M1, H5T_DIR_DESCEND)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
#ifdef H5_HAVE__FLOAT16
|
||||
if (true != H5Tequal(native_type, H5T_NATIVE_FLOAT16))
|
||||
TEST_ERROR;
|
||||
#else
|
||||
if (true != H5Tequal(native_type, H5T_NATIVE_FLOAT))
|
||||
TEST_ERROR;
|
||||
#endif
|
||||
|
||||
if (H5Tclose(native_type) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
PASSED();
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY
|
||||
{
|
||||
H5Tclose(native_type);
|
||||
}
|
||||
H5E_END_TRY
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef H5_HAVE_COMPLEX_NUMBERS
|
||||
static herr_t
|
||||
test_complex(hid_t file)
|
||||
@@ -3561,6 +3617,7 @@ main(void)
|
||||
nerrors += test_bfloat16() < 0 ? 1 : 0;
|
||||
nerrors += test_fp8() < 0 ? 1 : 0;
|
||||
nerrors += test_fp6() < 0 ? 1 : 0;
|
||||
nerrors += test_fp4() < 0 ? 1 : 0;
|
||||
|
||||
#ifdef H5_HAVE_COMPLEX_NUMBERS
|
||||
nerrors += test_complex(file) < 0 ? 1 : 0;
|
||||
|
||||
Reference in New Issue
Block a user