mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-09-25 04:09:44 +03:00
Makes testing parameters specified with AddTest non-const again when passed to test functions. This allows test functions to update their parameters during execution and is particularly useful for tests which use those parameters to accumulate statistics, error counts, etc. without resorting to global variables.
515 lines
17 KiB
C++
515 lines
17 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. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/*****************************************************************************
|
|
FILE
|
|
tarray.cpp - HDF5 C++ testing the array datatype functionality
|
|
|
|
***************************************************************************/
|
|
#include <iostream>
|
|
using std::cerr;
|
|
using std::endl;
|
|
|
|
#include <string>
|
|
#include "H5Cpp.h" // C++ API header file
|
|
using namespace H5;
|
|
|
|
#include "h5test.h"
|
|
#include "h5cpputil.h" // C++ utilility header file
|
|
|
|
const H5std_string FILENAME("tarray.h5");
|
|
const H5std_string ARRAYTYPE_NAME("/Array type 1");
|
|
const int SPACE1_RANK = 1;
|
|
const hsize_t SPACE1_DIM1 = 4;
|
|
const int ARRAY1_RANK = 1;
|
|
const hsize_t ARRAY1_DIM1 = 4;
|
|
|
|
typedef enum flt_t { FLT_FLOAT, FLT_DOUBLE, FLT_LDOUBLE, FLT_OTHER } flt_t;
|
|
|
|
typedef enum int_t {
|
|
INT_CHAR,
|
|
INT_UCHAR,
|
|
INT_SHORT,
|
|
INT_USHORT,
|
|
INT_INT,
|
|
INT_UINT,
|
|
INT_LONG,
|
|
INT_ULONG,
|
|
INT_LLONG,
|
|
INT_ULLONG,
|
|
INT_OTHER
|
|
} int_t;
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_array_compound_array
|
|
*
|
|
* Purpose Tests 1-D array of compound datatypes (with array fields)
|
|
*
|
|
* Return None
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static void
|
|
test_array_compound_array()
|
|
{
|
|
SUBTEST("ArrayType::getArrayNDims & ArrayType::getArrayDims");
|
|
typedef struct { // Typedef for compound datatype */
|
|
int i;
|
|
float f[ARRAY1_DIM1];
|
|
} s1_t;
|
|
s1_t wdata[SPACE1_DIM1][ARRAY1_DIM1]; // Information to write
|
|
s1_t rdata[SPACE1_DIM1][ARRAY1_DIM1]; // Information read in
|
|
hsize_t sdims1[] = {SPACE1_DIM1};
|
|
hsize_t tdims1[] = {ARRAY1_DIM1};
|
|
int nmemb; // Number of compound members
|
|
int ii; // counting variables
|
|
hsize_t idxi, idxj, idxk; // dimension indicing variables
|
|
H5T_class_t mclass; // Datatype class for field
|
|
|
|
// Initialize array data to write
|
|
for (idxi = 0; idxi < SPACE1_DIM1; idxi++)
|
|
for (idxj = 0; idxj < ARRAY1_DIM1; idxj++) {
|
|
wdata[idxi][idxj].i = static_cast<int>(idxi * 10 + idxj);
|
|
for (idxk = 0; idxk < ARRAY1_DIM1; idxk++) {
|
|
float temp = static_cast<float>(idxi) * 10.0F + static_cast<float>(idxj) * 2.5F +
|
|
static_cast<float>(idxk);
|
|
wdata[idxi][idxj].f[idxk] = temp;
|
|
}
|
|
} // end for
|
|
|
|
try {
|
|
// Create File
|
|
H5File file1(FILENAME, H5F_ACC_TRUNC);
|
|
|
|
// Create dataspace for datasets
|
|
DataSpace space(SPACE1_RANK, sdims1, NULL);
|
|
|
|
/*
|
|
* Create an array datatype of compounds, arrtype. Each compound
|
|
* datatype, comptype, contains an integer and an array of floats,
|
|
* arrfltype.
|
|
*/
|
|
|
|
// Create a compound datatype
|
|
CompType comptype(sizeof(s1_t));
|
|
|
|
// Insert integer field
|
|
comptype.insertMember("i", HOFFSET(s1_t, i), PredType::NATIVE_INT);
|
|
|
|
// Create an array of floats datatype
|
|
ArrayType arrfltype(PredType::NATIVE_FLOAT, ARRAY1_RANK, tdims1);
|
|
|
|
// Insert float array field
|
|
comptype.insertMember("f", HOFFSET(s1_t, f), arrfltype);
|
|
|
|
// Close array of floats field datatype
|
|
arrfltype.close();
|
|
|
|
// Create an array datatype of the compound datatype
|
|
ArrayType arrtype(comptype, ARRAY1_RANK, tdims1);
|
|
|
|
// Close compound datatype comptype
|
|
comptype.close();
|
|
|
|
// Create a dataset
|
|
DataSet dataset = file1.createDataSet("Dataset1", arrtype, space);
|
|
|
|
// Write dataset to disk
|
|
dataset.write(wdata, arrtype);
|
|
|
|
// Test opening ArrayType with opening constructor (Dec 2016)
|
|
|
|
// Commit the arrtype to give it a name
|
|
arrtype.commit(file1, ARRAYTYPE_NAME);
|
|
|
|
// Close it, then re-open with the opening constructor
|
|
arrtype.close();
|
|
ArrayType named_type(file1, ARRAYTYPE_NAME);
|
|
|
|
// Get and verify the type's name
|
|
H5std_string type_name = named_type.getObjName();
|
|
verify_val(type_name, ARRAYTYPE_NAME, "DataType::getObjName tests constructor", __LINE__, __FILE__);
|
|
named_type.close();
|
|
|
|
// Close all
|
|
dataset.close();
|
|
space.close();
|
|
file1.close();
|
|
|
|
// Re-open file
|
|
file1.openFile(FILENAME, H5F_ACC_RDONLY);
|
|
|
|
// Open the dataset
|
|
dataset = file1.openDataSet("Dataset1");
|
|
|
|
/*
|
|
* Check the datatype array of compounds
|
|
*/
|
|
|
|
// Verify that it is an array of compounds
|
|
DataType dstype = dataset.getDataType();
|
|
mclass = dstype.getClass();
|
|
verify_val(mclass == H5T_ARRAY, true, "f2_type.getClass", __LINE__, __FILE__);
|
|
|
|
dstype.close();
|
|
|
|
// Get the array datatype to check
|
|
ArrayType atype_check = dataset.getArrayType();
|
|
|
|
// Check the array rank
|
|
int ndims = atype_check.getArrayNDims();
|
|
verify_val(ndims, ARRAY1_RANK, "atype_check.getArrayNDims", __LINE__, __FILE__);
|
|
|
|
// Get the array dimensions
|
|
hsize_t rdims1[H5S_MAX_RANK];
|
|
atype_check.getArrayDims(rdims1);
|
|
|
|
// Check the array dimensions
|
|
for (ii = 0; ii < ndims; ii++)
|
|
if (rdims1[ii] != tdims1[ii]) {
|
|
TestErrPrintf("Array dimension information doesn't match!, rdims1[%d]=%" PRIuHSIZE
|
|
", tdims1[%d]=%" PRIuHSIZE "\n",
|
|
ii, rdims1[ii], ii, tdims1[ii]);
|
|
continue;
|
|
} // end if
|
|
|
|
// Test ArrayType::ArrayType(const hid_t existing_id)
|
|
ArrayType new_arrtype(atype_check.getId());
|
|
|
|
// Check the array rank
|
|
ndims = new_arrtype.getArrayNDims();
|
|
verify_val(ndims, ARRAY1_RANK, "new_arrtype.getArrayNDims", __LINE__, __FILE__);
|
|
|
|
// Get the array dimensions
|
|
new_arrtype.getArrayDims(rdims1);
|
|
|
|
// Check the array dimensions
|
|
for (ii = 0; ii < ndims; ii++)
|
|
if (rdims1[ii] != tdims1[ii]) {
|
|
TestErrPrintf("Array dimension information doesn't match!, rdims1[%d]=%" PRIuHSIZE
|
|
", tdims1[%d]=%" PRIuHSIZE "\n",
|
|
ii, rdims1[ii], ii, tdims1[ii]);
|
|
continue;
|
|
} // end if
|
|
|
|
/*
|
|
* Check the compound datatype and the array of floats datatype
|
|
* in the compound.
|
|
*/
|
|
// Get the compound datatype, which is the base datatype of the
|
|
// array datatype atype_check.
|
|
DataType base_type = atype_check.getSuper();
|
|
mclass = base_type.getClass();
|
|
verify_val(mclass == H5T_COMPOUND, true, "atype_check.getClass", __LINE__, __FILE__);
|
|
|
|
// Verify the compound datatype info
|
|
CompType ctype_check(base_type.getId());
|
|
base_type.close();
|
|
|
|
// Check the number of members
|
|
nmemb = ctype_check.getNmembers();
|
|
verify_val(nmemb, 2, "ctype_check.getNmembers", __LINE__, __FILE__);
|
|
|
|
// Check the 2nd field's name
|
|
H5std_string field2_name = ctype_check.getMemberName(1);
|
|
if (strcmp(field2_name.c_str(), "f") != 0)
|
|
TestErrPrintf("Compound field name doesn't match!, field2_name=%s\n", field2_name.c_str());
|
|
|
|
// Get the 2nd field's datatype
|
|
DataType f2_type = ctype_check.getMemberDataType(1);
|
|
|
|
// Get the 2nd field's class, this 2nd field should have an array type
|
|
mclass = f2_type.getClass();
|
|
verify_val(mclass == H5T_ARRAY, true, "f2_type.getClass", __LINE__, __FILE__);
|
|
f2_type.close();
|
|
|
|
// Get the 2nd field, array of floats datatype, to check
|
|
ArrayType f2_atype_check = ctype_check.getMemberArrayType(1);
|
|
|
|
// Check the array rank
|
|
ndims = f2_atype_check.getArrayNDims();
|
|
verify_val(ndims, ARRAY1_RANK, "f2_atype_check.getArrayNDims", __LINE__, __FILE__);
|
|
|
|
// Get the array dimensions
|
|
memset(rdims1, 0, sizeof(rdims1));
|
|
f2_atype_check.getArrayDims(rdims1);
|
|
|
|
// Check the array dimensions
|
|
for (ii = 0; ii < ndims; ii++)
|
|
if (rdims1[ii] != tdims1[ii]) {
|
|
TestErrPrintf("Array dimension information doesn't match!, rdims1[%d]=%" PRIuHSIZE
|
|
", tdims1[%d]=%" PRIuHSIZE "\n",
|
|
ii, rdims1[ii], ii, tdims1[ii]);
|
|
continue;
|
|
} // end if
|
|
|
|
// Close done datatypes
|
|
f2_atype_check.close();
|
|
ctype_check.close();
|
|
|
|
// Read dataset from disk
|
|
dataset.read(rdata, atype_check);
|
|
|
|
// Compare data read in
|
|
for (idxi = 0; idxi < SPACE1_DIM1; idxi++) {
|
|
for (idxj = 0; idxj < ARRAY1_DIM1; idxj++) {
|
|
if (wdata[idxi][idxj].i != rdata[idxi][idxj].i) {
|
|
TestErrPrintf("Array data information doesn't match!, wdata[%" PRIuHSIZE "][%" PRIuHSIZE
|
|
"].i=%d, "
|
|
"rdata[%" PRIuHSIZE "][%" PRIuHSIZE "].i=%d\n",
|
|
idxi, idxj, wdata[idxi][idxj].i, idxi, idxj, rdata[idxi][idxj].i);
|
|
continue;
|
|
} // end if
|
|
} // end for
|
|
} // end for
|
|
|
|
// Close all
|
|
atype_check.close();
|
|
dataset.close();
|
|
file1.close();
|
|
PASSED();
|
|
} // end of try block
|
|
catch (Exception &E) {
|
|
issue_fail_msg("test_array_compound_array", __LINE__, __FILE__, E.getCDetailMsg());
|
|
}
|
|
|
|
} // end test_array_compound_array()
|
|
|
|
/*
|
|
* Helper routine to demonstrate the issue in HDFFV-9562
|
|
*/
|
|
static H5::DataType
|
|
getArr()
|
|
{
|
|
hsize_t *dims = new hsize_t;
|
|
*dims = 5;
|
|
H5::ArrayType ret;
|
|
ret = H5::ArrayType(H5::PredType::NATIVE_INT, 1, dims);
|
|
delete dims;
|
|
return ret;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_array_assignment
|
|
*
|
|
* Purpose Tests the operator=
|
|
*
|
|
* Return None
|
|
*
|
|
* Description:
|
|
* Used user's sample code in HDFFV-9562
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static void
|
|
test_array_assignment()
|
|
{
|
|
hsize_t sdims1[] = {SPACE1_DIM1};
|
|
SUBTEST("ArrayType::operator=");
|
|
|
|
try {
|
|
// Create File
|
|
H5File file1(FILENAME, H5F_ACC_TRUNC);
|
|
|
|
// Create dataspace for datasets
|
|
DataSpace space(SPACE1_RANK, sdims1, NULL);
|
|
|
|
/*
|
|
* Create an array datatype of compounds, arrtype. Each compound
|
|
* datatype, comptype, contains an integer and an array of floats,
|
|
* arrfltype.
|
|
*/
|
|
|
|
// Create a compound datatype
|
|
CompType comptype(static_cast<size_t>(24));
|
|
|
|
// Insert integer field
|
|
comptype.insertMember("i", 0, PredType::NATIVE_INT);
|
|
|
|
// Insert float array field
|
|
comptype.insertMember("a", 4, getArr());
|
|
|
|
// Create a dataset
|
|
DataSet dataset = file1.createDataSet("Dataset1", comptype, space);
|
|
|
|
// Close all
|
|
dataset.close();
|
|
comptype.close();
|
|
space.close();
|
|
file1.close();
|
|
|
|
PASSED();
|
|
} // end of try block
|
|
catch (Exception &E) {
|
|
issue_fail_msg("test_array_assignment", __LINE__, __FILE__, E.getCDetailMsg());
|
|
}
|
|
} // end test_array_assignment()
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_array_info
|
|
*
|
|
* Purpose Tests getting array information using the const methods.
|
|
*
|
|
* Return None
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static void
|
|
test_array_info()
|
|
{
|
|
SUBTEST("ArrayType Const Methods");
|
|
typedef struct { // Typedef for compound datatype */
|
|
int i;
|
|
float f[ARRAY1_DIM1];
|
|
} s1_t;
|
|
s1_t wdata[SPACE1_DIM1][ARRAY1_DIM1]; // Information to write
|
|
hsize_t sdims1[] = {SPACE1_DIM1};
|
|
hsize_t tdims1[] = {ARRAY1_DIM1};
|
|
int ii; // counting variables
|
|
hsize_t idxi, idxj, idxk; // dimension indicing variables
|
|
H5T_class_t mclass; // Datatype class for field
|
|
|
|
// Initialize array data to write
|
|
for (idxi = 0; idxi < SPACE1_DIM1; idxi++)
|
|
for (idxj = 0; idxj < ARRAY1_DIM1; idxj++) {
|
|
wdata[idxi][idxj].i = static_cast<int>(idxi * 10 + idxj);
|
|
for (idxk = 0; idxk < ARRAY1_DIM1; idxk++) {
|
|
float temp = static_cast<float>(idxi) * 10.0F + static_cast<float>(idxj) * 2.5F +
|
|
static_cast<float>(idxk);
|
|
wdata[idxi][idxj].f[idxk] = temp;
|
|
}
|
|
}
|
|
|
|
try {
|
|
// Create File
|
|
H5File file1(FILENAME, H5F_ACC_TRUNC);
|
|
|
|
// Create dataspace for datasets
|
|
DataSpace space(SPACE1_RANK, sdims1, NULL);
|
|
|
|
/*
|
|
* Create some array datatypes, then close the file.
|
|
*/
|
|
|
|
// Create an array of floats datatype
|
|
ArrayType arrfltype(PredType::NATIVE_FLOAT, ARRAY1_RANK, tdims1);
|
|
|
|
// Create an array datatype of the compound datatype
|
|
ArrayType arrtype(PredType::NATIVE_UINT, ARRAY1_RANK, tdims1);
|
|
|
|
// Create a dataset
|
|
DataSet dataset = file1.createDataSet("Dataset1", arrtype, space);
|
|
|
|
// Write dataset to disk
|
|
dataset.write(wdata, arrtype);
|
|
|
|
// Close array of floats field datatype
|
|
arrfltype.close();
|
|
|
|
// Close all
|
|
dataset.close();
|
|
arrtype.close();
|
|
space.close();
|
|
file1.close();
|
|
|
|
// Re-open file
|
|
file1.openFile(FILENAME, H5F_ACC_RDONLY);
|
|
|
|
// Open the dataset
|
|
dataset = file1.openDataSet("Dataset1");
|
|
|
|
/*
|
|
* Check the datatype array of compounds
|
|
*/
|
|
|
|
// Verify that it is an array of compounds
|
|
DataType dstype = dataset.getDataType();
|
|
mclass = dstype.getClass();
|
|
verify_val(mclass == H5T_ARRAY, true, "f2_type.getClass", __LINE__, __FILE__);
|
|
|
|
dstype.close();
|
|
|
|
{ // Let atype_check go out of scope
|
|
// Get the array datatype, declared as const
|
|
const ArrayType atype_check = dataset.getArrayType();
|
|
|
|
// Check the array rank with the const method
|
|
int ndims = atype_check.getArrayNDims();
|
|
verify_val(ndims, ARRAY1_RANK, "atype_check.getArrayNDims", __LINE__, __FILE__);
|
|
|
|
// Get the array dimensions with the const method
|
|
hsize_t rdims1[H5S_MAX_RANK];
|
|
atype_check.getArrayDims(rdims1);
|
|
|
|
// Check the array dimensions
|
|
for (ii = 0; ii < ndims; ii++)
|
|
if (rdims1[ii] != tdims1[ii]) {
|
|
TestErrPrintf("Array dimension information doesn't match!, rdims1[%d]=%" PRIuHSIZE
|
|
", tdims1[%d]=%" PRIuHSIZE "\n",
|
|
ii, rdims1[ii], ii, tdims1[ii]);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Close all
|
|
dataset.close();
|
|
file1.close();
|
|
PASSED();
|
|
} // end of try block
|
|
catch (Exception &E) {
|
|
issue_fail_msg("test_array_info", __LINE__, __FILE__, E.getCDetailMsg());
|
|
}
|
|
|
|
} // end test_array_info()
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: test_array
|
|
*
|
|
* Purpose Main datatypes testing routine
|
|
*
|
|
* Return None
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
extern "C" void
|
|
test_array(void *params)
|
|
{
|
|
(void)params;
|
|
|
|
// Output message about test being performed
|
|
MESSAGE(5, ("Testing Array Datatypes\n"));
|
|
|
|
// Test array of compounds with array field
|
|
test_array_compound_array();
|
|
|
|
// Test operator= (HDFFV-9562)
|
|
test_array_assignment();
|
|
|
|
// Test const functions (HDFFV-9725)
|
|
test_array_info();
|
|
|
|
} // test_array()
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: cleanup_array
|
|
*
|
|
* Purpose Cleanup temporary test files
|
|
*
|
|
* Return None
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
extern "C" void
|
|
cleanup_array(void *params)
|
|
{
|
|
(void)params;
|
|
|
|
if (GetTestCleanup()) {
|
|
HDremove(FILENAME.c_str());
|
|
}
|
|
} // cleanup_array
|