mirror of
https://github.com/nasa/trick.git
synced 2025-05-09 20:13:01 +00:00
Resolved the segmentation fault issue when loading a checkpoint with HDF5 data recording enabled. (#1837)
* Resolved the segmentation fault issue when loading a checkpoint with HDF5 data recording enabled. Resolved the segmentation fault issue when loading a checkpoint with HDF5 data recording enabled. * Fixed bitfield for hdf5 Fixed bitfield for hdf5 recording.
This commit is contained in:
parent
d98eef4b66
commit
fd6df3cf33
@ -37,16 +37,6 @@ PROGRAMMERS:
|
|||||||
|
|
||||||
namespace Trick {
|
namespace Trick {
|
||||||
|
|
||||||
#ifdef HDF5
|
|
||||||
#ifndef TRICK_ICG
|
|
||||||
struct HDF5_INFO {
|
|
||||||
hid_t dataset;
|
|
||||||
Trick::DataRecordBuffer * drb ;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The DRHDF5 recording format is an industry conforming HDF5 formatted file. Files written in this format are named
|
The DRHDF5 recording format is an industry conforming HDF5 formatted file. Files written in this format are named
|
||||||
log_<group_name>.h5. The contents of this file type are readable by the Trick Data Products packages from
|
log_<group_name>.h5. The contents of this file type are readable by the Trick Data Products packages from
|
||||||
@ -56,6 +46,9 @@ namespace Trick {
|
|||||||
@verbatim
|
@verbatim
|
||||||
GROUP "/" {
|
GROUP "/" {
|
||||||
GROUP "header" {
|
GROUP "header" {
|
||||||
|
DATASET "byte_order" {
|
||||||
|
"little_endian"
|
||||||
|
}
|
||||||
DATASET "file_names" {
|
DATASET "file_names" {
|
||||||
"param_1_file_name", "param_2_file_name", etc...
|
"param_1_file_name", "param_2_file_name", etc...
|
||||||
}
|
}
|
||||||
@ -133,10 +126,29 @@ GROUP "/" {
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
#ifdef HDF5
|
#ifdef HDF5
|
||||||
std::vector<HDF5_INFO *> parameters; // trick_io(**)
|
/**
|
||||||
|
The HDF5 file handle.
|
||||||
|
*/
|
||||||
hid_t file; // trick_io(**)
|
hid_t file; // trick_io(**)
|
||||||
|
/**
|
||||||
|
Root group and header group in the HDF5 file.
|
||||||
|
*/
|
||||||
hid_t root_group, header_group; // trick_io(**)
|
hid_t root_group, header_group; // trick_io(**)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Parameter names array to be used in the HDF5 packet table.
|
||||||
|
Each array item is a string of the parameter name that is
|
||||||
|
the copy of the reference name.
|
||||||
|
This is needed so when the dataset is closed, the reference
|
||||||
|
name in rec_buffer is still valid and won't cause double
|
||||||
|
deleting when variables are removed from rec_buffer.
|
||||||
|
*/
|
||||||
|
char** param_names; // trick_io(**)
|
||||||
|
|
||||||
|
/**
|
||||||
|
The dataset ids for each parameter.
|
||||||
|
*/
|
||||||
|
hid_t* param_dataset_ids; // trick_io(**)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} ;
|
} ;
|
||||||
|
43
test/SIM_test_dr/Modified_data/dr_bitfHDF5.dr
Normal file
43
test/SIM_test_dr/Modified_data/dr_bitfHDF5.dr
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
global DR_GROUP_ID
|
||||||
|
global drg
|
||||||
|
try:
|
||||||
|
if DR_GROUP_ID >= 0:
|
||||||
|
DR_GROUP_ID += 1
|
||||||
|
except NameError:
|
||||||
|
DR_GROUP_ID = 0
|
||||||
|
drg = []
|
||||||
|
|
||||||
|
drg.append(trick.DRHDF5("DR_bitfieldsHDF5"))
|
||||||
|
drg[DR_GROUP_ID].set_freq(trick.DR_Always)
|
||||||
|
drg[DR_GROUP_ID].set_cycle(0.1)
|
||||||
|
drg[DR_GROUP_ID].set_single_prec_only(False)
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.charB.var1")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.charB.var2")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.charB.var3")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.charB.var4")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.intB.var1")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.intB.var2")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.intB.var3")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.intB.var4")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.shortB.var1")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.shortB.var2")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.shortB.var3")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.shortB.var4")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.ucharB.var1")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.ucharB.var2")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.ucharB.var3")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.ucharB.var4")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.uintB.var1")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.uintB.var2")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.uintB.var3")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.uintB.var4")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.ushortB.var1")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.ushortB.var2")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.ushortB.var3")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.ushortB.var4")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.mixB.var1")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.mixB.var2")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.mixB.var3")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.mixB.var4")
|
||||||
|
trick.add_data_record_group(drg[DR_GROUP_ID], trick.DR_Buffer)
|
||||||
|
drg[DR_GROUP_ID].enable()
|
38
test/SIM_test_dr/Modified_data/dr_typesHDF5.dr
Normal file
38
test/SIM_test_dr/Modified_data/dr_typesHDF5.dr
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
global DR_GROUP_ID
|
||||||
|
global drg
|
||||||
|
try:
|
||||||
|
if DR_GROUP_ID >= 0:
|
||||||
|
DR_GROUP_ID += 1
|
||||||
|
except NameError:
|
||||||
|
DR_GROUP_ID = 0
|
||||||
|
drg = []
|
||||||
|
|
||||||
|
drg.append(trick.DRHDF5("DR_typesHDF5"))
|
||||||
|
drg[DR_GROUP_ID].set_freq(trick.DR_Always)
|
||||||
|
drg[DR_GROUP_ID].set_cycle(0.1)
|
||||||
|
drg[DR_GROUP_ID].set_single_prec_only(False)
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.a")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.b")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.c")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.d")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.e")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.f")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.g")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.h")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.i")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.j")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.k")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.l")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.m")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.n")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.o")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.p")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.q[0]")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.q[1]")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.q[2]")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.q[3]")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.q[4]")
|
||||||
|
drg[DR_GROUP_ID].add_variable("drx.drt.r[0][0]")
|
||||||
|
|
||||||
|
trick.add_data_record_group(drg[DR_GROUP_ID], trick.DR_Buffer)
|
||||||
|
drg[DR_GROUP_ID].enable()
|
BIN
test/SIM_test_dr/RUN_test/Ref_Logs/log_DR_bitfieldsHDF5.h5
Normal file
BIN
test/SIM_test_dr/RUN_test/Ref_Logs/log_DR_bitfieldsHDF5.h5
Normal file
Binary file not shown.
BIN
test/SIM_test_dr/RUN_test/Ref_Logs/log_DR_typesHDF5.h5
Normal file
BIN
test/SIM_test_dr/RUN_test/Ref_Logs/log_DR_typesHDF5.h5
Normal file
Binary file not shown.
@ -5,6 +5,10 @@ trick_utest.unit_tests.set_file_name( os.getenv("TRICK_HOME") + "/trick_test/SIM
|
|||||||
|
|
||||||
trick_utest.unit_tests.set_test_name( "DRTest" )
|
trick_utest.unit_tests.set_test_name( "DRTest" )
|
||||||
|
|
||||||
|
has_dhf5 = False
|
||||||
|
if hasattr(trick, 'DRHDF5'):
|
||||||
|
has_dhf5 = True
|
||||||
|
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
|
|
||||||
test_suite = "drg api"
|
test_suite = "drg api"
|
||||||
@ -16,6 +20,14 @@ num_drgs = trick.get_num_data_record_groups()
|
|||||||
TRICK_EXPECT_EQ( num_drgs , 0 , test_suite , "0 drgs before any created" )
|
TRICK_EXPECT_EQ( num_drgs , 0 , test_suite , "0 drgs before any created" )
|
||||||
|
|
||||||
# The first item of each pair is the .dr file name and the second item of each pair is the drg name
|
# The first item of each pair is the .dr file name and the second item of each pair is the drg name
|
||||||
|
if has_dhf5:
|
||||||
|
dr_file_name_drg_name_tuple = (('Modified_data/dr_typesASCII.dr', 'DR_typesASCII'),
|
||||||
|
('Modified_data/dr_typesBINARY.dr', 'DR_typesBINARY'),
|
||||||
|
('Modified_data/dr_typesHDF5.dr', 'DR_typesHDF5'),
|
||||||
|
('Modified_data/dr_bitfASCII.dr', 'DR_bitfieldsASCII'),
|
||||||
|
('Modified_data/dr_bitfBINARY.dr', 'DR_bitfieldsBINARY'),
|
||||||
|
('Modified_data/dr_bitfHDF5.dr', 'DR_bitfieldsHDF5'))
|
||||||
|
else:
|
||||||
dr_file_name_drg_name_tuple = (('Modified_data/dr_typesASCII.dr', 'DR_typesASCII'),
|
dr_file_name_drg_name_tuple = (('Modified_data/dr_typesASCII.dr', 'DR_typesASCII'),
|
||||||
('Modified_data/dr_typesBINARY.dr', 'DR_typesBINARY'),
|
('Modified_data/dr_typesBINARY.dr', 'DR_typesBINARY'),
|
||||||
('Modified_data/dr_bitfASCII.dr', 'DR_bitfieldsASCII'),
|
('Modified_data/dr_bitfASCII.dr', 'DR_bitfieldsASCII'),
|
||||||
@ -29,6 +41,9 @@ for i in range(num_files):
|
|||||||
num_drgs = trick.get_num_data_record_groups()
|
num_drgs = trick.get_num_data_record_groups()
|
||||||
|
|
||||||
# Check the result of trick.get_num_data_record_groups()
|
# Check the result of trick.get_num_data_record_groups()
|
||||||
|
if has_dhf5:
|
||||||
|
TRICK_EXPECT_EQ( num_drgs , 6 , test_suite , "num of dr groups = 6" )
|
||||||
|
else:
|
||||||
TRICK_EXPECT_EQ( num_drgs , 4 , test_suite , "num of dr groups = 4" )
|
TRICK_EXPECT_EQ( num_drgs , 4 , test_suite , "num of dr groups = 4" )
|
||||||
|
|
||||||
# Test trick.get_data_record_group(<drg_name>) for getting the drg pointer by its name
|
# Test trick.get_data_record_group(<drg_name>) for getting the drg pointer by its name
|
||||||
@ -49,6 +64,9 @@ TRICK_EXPECT_TRUE( is_null, test_suite , "null drg by nonexistent drg name" )
|
|||||||
is_null = False
|
is_null = False
|
||||||
if trick.get_data_record_group_by_idx(num_drgs+1) is None :
|
if trick.get_data_record_group_by_idx(num_drgs+1) is None :
|
||||||
is_null = True
|
is_null = True
|
||||||
|
if has_dhf5:
|
||||||
|
TRICK_EXPECT_TRUE( is_null, test_suite , "null drg by drg id 7" )
|
||||||
|
else:
|
||||||
TRICK_EXPECT_TRUE( is_null, test_suite , "null drg by drg id 5" )
|
TRICK_EXPECT_TRUE( is_null, test_suite , "null drg by drg id 5" )
|
||||||
|
|
||||||
is_null = False
|
is_null = False
|
||||||
|
@ -13,6 +13,7 @@ PROGRAMMERS:
|
|||||||
#include "trick/command_line_protos.h"
|
#include "trick/command_line_protos.h"
|
||||||
#include "trick/memorymanager_c_intf.h"
|
#include "trick/memorymanager_c_intf.h"
|
||||||
#include "trick/message_proto.h"
|
#include "trick/message_proto.h"
|
||||||
|
#include "trick/bitfield_proto.h"
|
||||||
|
|
||||||
Trick::DRHDF5::DRHDF5( std::string in_name, Trick::DR_Type dr_type ) : Trick::DataRecordGroup(in_name, dr_type) {
|
Trick::DRHDF5::DRHDF5( std::string in_name, Trick::DR_Type dr_type ) : Trick::DataRecordGroup(in_name, dr_type) {
|
||||||
register_group_with_mm(this, "Trick::DRHDF5") ;
|
register_group_with_mm(this, "Trick::DRHDF5") ;
|
||||||
@ -38,7 +39,6 @@ int Trick::DRHDF5::format_specific_init() {
|
|||||||
|
|
||||||
#ifdef HDF5
|
#ifdef HDF5
|
||||||
unsigned int ii ;
|
unsigned int ii ;
|
||||||
HDF5_INFO *hdf5_info ;
|
|
||||||
hsize_t chunk_size = 1024;
|
hsize_t chunk_size = 1024;
|
||||||
hid_t byte_id ;
|
hid_t byte_id ;
|
||||||
hid_t file_names_id, param_types_id, param_units_id, param_names_id ;
|
hid_t file_names_id, param_types_id, param_units_id, param_names_id ;
|
||||||
@ -58,11 +58,21 @@ int Trick::DRHDF5::format_specific_init() {
|
|||||||
return -1 ;
|
return -1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check file validity first
|
||||||
|
if (H5Iis_valid(file) <= 0) {
|
||||||
|
message_publish(MSG_ERROR, "File handle invalid, id=%lld\n", (long long)file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
// All HDF5 objects live in the top-level "/" (root) group.
|
// All HDF5 objects live in the top-level "/" (root) group.
|
||||||
root_group = H5Gopen(file, "/", H5P_DEFAULT);
|
root_group = H5Gopen(file, "/", H5P_DEFAULT);
|
||||||
|
|
||||||
// Create a new group named "header" at the root ("/") level.
|
// Create a new group named "header" at the root ("/") level.
|
||||||
header_group = H5Gcreate(file, "/header", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
|
header_group = H5Gcreate(file, "/header", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
|
||||||
|
// Validate header group
|
||||||
|
if (H5Iis_valid(header_group) <= 0) {
|
||||||
|
message_publish(MSG_ERROR, "Header group invalid, id=%lld\n", (long long)header_group);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
// Create a packet table (PT) that stores byte order.
|
// Create a packet table (PT) that stores byte order.
|
||||||
byte_id = H5PTcreate_fl(header_group, "byte_order", s256, chunk_size, 1) ;
|
byte_id = H5PTcreate_fl(header_group, "byte_order", s256, chunk_size, 1) ;
|
||||||
// Add the byte order value to the byte packet table.
|
// Add the byte order value to the byte packet table.
|
||||||
@ -76,11 +86,14 @@ int Trick::DRHDF5::format_specific_init() {
|
|||||||
// Create a packet table (PT) that stores each parameter's name.
|
// Create a packet table (PT) that stores each parameter's name.
|
||||||
param_names_id = H5PTcreate_fl(header_group, "param_names", s256, chunk_size, 1) ;
|
param_names_id = H5PTcreate_fl(header_group, "param_names", s256, chunk_size, 1) ;
|
||||||
|
|
||||||
|
// Allocate memory for the parameter names
|
||||||
|
param_names = new char*[rec_buffer.size()];
|
||||||
|
// Allocate memory for the dataset ids
|
||||||
|
param_dataset_ids = new hid_t[rec_buffer.size()];
|
||||||
|
|
||||||
// Create a table for each requested parameter.
|
// Create a table for each requested parameter.
|
||||||
for (ii = 0; ii < rec_buffer.size(); ii++) {
|
for (ii = 0; ii < rec_buffer.size(); ii++) {
|
||||||
|
|
||||||
hdf5_info = (HDF5_INFO *)malloc(sizeof(HDF5_INFO));
|
|
||||||
|
|
||||||
/* Case statements taken from "parameter_types.h."
|
/* Case statements taken from "parameter_types.h."
|
||||||
* HDF5 Native types found in "H5Tpublic.h." */
|
* HDF5 Native types found in "H5Tpublic.h." */
|
||||||
switch (rec_buffer[ii]->ref->attr->type) {
|
switch (rec_buffer[ii]->ref->attr->type) {
|
||||||
@ -128,9 +141,9 @@ int Trick::DRHDF5::format_specific_init() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TRICK_UNSIGNED_BITFIELD:
|
case TRICK_UNSIGNED_BITFIELD:
|
||||||
if (rec_buffer[ii]->ref->attr->size == sizeof(int)) {
|
if (rec_buffer[ii]->ref->attr->size == sizeof(unsigned int)) {
|
||||||
datatype = H5T_NATIVE_UINT;
|
datatype = H5T_NATIVE_UINT;
|
||||||
} else if (rec_buffer[ii]->ref->attr->size == sizeof(short)) {
|
} else if (rec_buffer[ii]->ref->attr->size == sizeof(unsigned short)) {
|
||||||
datatype = H5T_NATIVE_USHORT;
|
datatype = H5T_NATIVE_USHORT;
|
||||||
} else {
|
} else {
|
||||||
datatype = H5T_NATIVE_UCHAR;
|
datatype = H5T_NATIVE_UCHAR;
|
||||||
@ -150,7 +163,6 @@ int Trick::DRHDF5::format_specific_init() {
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
free(hdf5_info);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,18 +182,19 @@ int Trick::DRHDF5::format_specific_init() {
|
|||||||
* RETURN:
|
* RETURN:
|
||||||
* Returns an identifier for the new packet table, or H5I_BADID on error.
|
* Returns an identifier for the new packet table, or H5I_BADID on error.
|
||||||
*/
|
*/
|
||||||
hdf5_info->dataset = H5PTcreate_fl(root_group, rec_buffer[ii]->ref->reference, datatype, chunk_size, 1) ;
|
// Allocate memory for the parameter names
|
||||||
|
param_names[ii] = (char *)malloc(strlen(rec_buffer[ii]->ref->reference) + 1);
|
||||||
if ( hdf5_info->dataset == H5I_BADID ) {
|
// Copy the parameter name to the list
|
||||||
|
strcpy(param_names[ii], rec_buffer[ii]->ref->reference);
|
||||||
|
// Create a packet table for each parameter
|
||||||
|
param_dataset_ids[ii] = H5PTcreate_fl(root_group, param_names[ii], datatype, chunk_size, 1) ;
|
||||||
|
// Validate the dataset
|
||||||
|
if ( param_dataset_ids[ii] == H5I_BADID ) {
|
||||||
message_publish(MSG_ERROR, "An error occured in data record group \"%s\" when adding \"%s\".\n",
|
message_publish(MSG_ERROR, "An error occured in data record group \"%s\" when adding \"%s\".\n",
|
||||||
group_name.c_str() , rec_buffer[ii]->ref->reference) ;
|
group_name.c_str() , param_names[ii]) ;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdf5_info->drb = rec_buffer[ii] ;
|
|
||||||
/* Add the new parameter element to the end of the vector.
|
|
||||||
* This effectively increases the vector size by one. */
|
|
||||||
parameters.push_back(hdf5_info);
|
|
||||||
|
|
||||||
// As a bonus, add a header entry for each parameter.
|
// As a bonus, add a header entry for each parameter.
|
||||||
/* File Name */
|
/* File Name */
|
||||||
buf = "log_" + group_name ;
|
buf = "log_" + group_name ;
|
||||||
@ -210,6 +223,105 @@ int Trick::DRHDF5::format_specific_init() {
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HDF5
|
||||||
|
/**
|
||||||
|
* Helper function to append specified data records for one variable to its dataset(packet table).
|
||||||
|
*/
|
||||||
|
void append_var_packet_table(Trick::DataRecordBuffer *drb, char* buf, size_t records, hid_t param_ds) {
|
||||||
|
// Data records to be appended to the packet table
|
||||||
|
void* data = 0;
|
||||||
|
int bf;
|
||||||
|
|
||||||
|
switch (drb->ref->attr->type) {
|
||||||
|
case TRICK_CHARACTER:
|
||||||
|
case TRICK_UNSIGNED_CHARACTER:
|
||||||
|
case TRICK_STRING:
|
||||||
|
case TRICK_SHORT:
|
||||||
|
case TRICK_UNSIGNED_SHORT:
|
||||||
|
case TRICK_ENUMERATED:
|
||||||
|
case TRICK_INTEGER:
|
||||||
|
case TRICK_UNSIGNED_INTEGER:
|
||||||
|
case TRICK_LONG:
|
||||||
|
case TRICK_UNSIGNED_LONG:
|
||||||
|
case TRICK_FLOAT:
|
||||||
|
case TRICK_DOUBLE:
|
||||||
|
H5PTappend(param_ds, records , buf);
|
||||||
|
break;
|
||||||
|
case TRICK_BITFIELD:
|
||||||
|
bf = GET_BITFIELD(buf, drb->ref->attr->size, drb->ref->attr->index[0].start, drb->ref->attr->index[0].size);
|
||||||
|
data = malloc(records * sizeof(bf));
|
||||||
|
|
||||||
|
// Extract bitfield for each record from different segments of buf
|
||||||
|
for (size_t j = 0; j < records; j++) {
|
||||||
|
// Calculate the correct offset in buf for each record
|
||||||
|
// Each record in buf has size of rec_buffer[ii]->ref->attr->size
|
||||||
|
size_t offset = j * drb->ref->attr->size;
|
||||||
|
|
||||||
|
if (drb->ref->attr->size == sizeof(int)) {
|
||||||
|
((int *)data)[j] = extract_bitfield_any(
|
||||||
|
*(int *)(buf+offset), drb->ref->attr->size,
|
||||||
|
drb->ref->attr->index[0].start, drb->ref->attr->index[0].size);
|
||||||
|
} else if (drb->ref->attr->size == sizeof(short)) {
|
||||||
|
((short *)data)[j] = extract_bitfield_any(
|
||||||
|
*(short *)(buf+offset), drb->ref->attr->size,
|
||||||
|
drb->ref->attr->index[0].start, drb->ref->attr->index[0].size);
|
||||||
|
} else if (drb->ref->attr->size == sizeof(char)) {
|
||||||
|
((char *)data)[j] = extract_bitfield_any(
|
||||||
|
*(char *)(buf+offset), drb->ref->attr->size,
|
||||||
|
drb->ref->attr->index[0].start, drb->ref->attr->index[0].size);
|
||||||
|
} else {
|
||||||
|
((int*)data)[j] = extract_bitfield_any(
|
||||||
|
*(int *)(buf+offset), drb->ref->attr->size,
|
||||||
|
drb->ref->attr->index[0].start, drb->ref->attr->index[0].size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
H5PTappend(param_ds, records, data);
|
||||||
|
break;
|
||||||
|
case TRICK_UNSIGNED_BITFIELD:
|
||||||
|
bf = GET_UNSIGNED_BITFIELD(buf, drb->ref->attr->size, drb->ref->attr->index[0].start, drb->ref->attr->index[0].size);
|
||||||
|
data = malloc(records * sizeof(bf));
|
||||||
|
|
||||||
|
// Extract bitfield for each record from different segments of buf
|
||||||
|
for (size_t j = 0; j < records; j++) {
|
||||||
|
// Calculate the correct offset in buf for each record
|
||||||
|
// Each record in buf has size of rec_buffer[ii]->ref->attr->size
|
||||||
|
size_t offset = j * drb->ref->attr->size; // record_size would be the size of one record in buf
|
||||||
|
|
||||||
|
if (drb->ref->attr->size == sizeof(int)) {
|
||||||
|
((unsigned int *)data)[j] = extract_unsigned_bitfield_any(
|
||||||
|
*(unsigned int *)(buf+offset), drb->ref->attr->size,
|
||||||
|
drb->ref->attr->index[0].start, drb->ref->attr->index[0].size);
|
||||||
|
} else if (drb->ref->attr->size == sizeof(short)) {
|
||||||
|
((unsigned short *)data)[j] = extract_unsigned_bitfield_any(
|
||||||
|
*(unsigned short *)(buf+offset), drb->ref->attr->size,
|
||||||
|
drb->ref->attr->index[0].start, drb->ref->attr->index[0].size);
|
||||||
|
} else if (drb->ref->attr->size == sizeof(char)) {
|
||||||
|
((unsigned char *)data)[j] = extract_unsigned_bitfield_any(
|
||||||
|
*(unsigned char *)(buf+offset), drb->ref->attr->size,
|
||||||
|
drb->ref->attr->index[0].start, drb->ref->attr->index[0].size);
|
||||||
|
} else {
|
||||||
|
((int *)data)[j] = extract_unsigned_bitfield_any(
|
||||||
|
*(int *)(buf+offset), drb->ref->attr->size,
|
||||||
|
drb->ref->attr->index[0].start, drb->ref->attr->index[0].size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
H5PTappend(param_ds, records, data);
|
||||||
|
break;
|
||||||
|
case TRICK_LONG_LONG:
|
||||||
|
case TRICK_UNSIGNED_LONG_LONG:
|
||||||
|
case TRICK_BOOLEAN:
|
||||||
|
default:
|
||||||
|
H5PTappend(param_ds, records , buf);
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (data != 0) {
|
||||||
|
free(data);
|
||||||
|
data = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
HDF5 logging is done on a per variable basis instead of per time step like the
|
HDF5 logging is done on a per variable basis instead of per time step like the
|
||||||
other recording methods. This write_data routine overrides the default in
|
other recording methods. This write_data routine overrides the default in
|
||||||
@ -223,6 +335,8 @@ int Trick::DRHDF5::write_data(bool must_write) {
|
|||||||
unsigned int num_to_write ;
|
unsigned int num_to_write ;
|
||||||
unsigned int ii;
|
unsigned int ii;
|
||||||
char *buf = 0;
|
char *buf = 0;
|
||||||
|
size_t ds_records1;
|
||||||
|
size_t ds_records2;
|
||||||
|
|
||||||
if ( record and inited and (buffer_type == DR_No_Buffer or must_write)) {
|
if ( record and inited and (buffer_type == DR_No_Buffer or must_write)) {
|
||||||
|
|
||||||
@ -238,31 +352,28 @@ int Trick::DRHDF5::write_data(bool must_write) {
|
|||||||
writer_num = local_buffer_num - num_to_write ;
|
writer_num = local_buffer_num - num_to_write ;
|
||||||
|
|
||||||
if ( writer_num != local_buffer_num ) {
|
if ( writer_num != local_buffer_num ) {
|
||||||
|
unsigned int writer_offset = writer_num % max_num ;
|
||||||
// Test if the writer pointer to the right of the buffer pointer in the ring
|
// Test if the writer pointer to the right of the buffer pointer in the ring
|
||||||
if ( (writer_num % max_num) > (local_buffer_num % max_num) ) {
|
if ( (writer_num % max_num) > (local_buffer_num % max_num) ) {
|
||||||
|
ds_records1 = max_num - writer_offset;
|
||||||
|
ds_records2 = local_buffer_num % max_num;
|
||||||
|
|
||||||
// we have 2 segments to write per variable
|
// we have 2 segments to write per variable
|
||||||
for (ii = 0; ii < parameters.size(); ii++) {
|
for (ii = 0; ii < rec_buffer.size(); ii++) {
|
||||||
HDF5_INFO * hi = parameters[ii] ;
|
//unsigned int writer_offset = writer_num % max_num ;
|
||||||
unsigned int writer_offset = writer_num % max_num ;
|
buf = rec_buffer[ii]->buffer + (writer_offset * rec_buffer[ii]->ref->attr->size) ;
|
||||||
buf = hi->drb->buffer + (writer_offset * hi->drb->ref->attr->size) ;
|
append_var_packet_table(rec_buffer[ii], buf, ds_records1, param_dataset_ids[ii]);
|
||||||
|
|
||||||
/* Append all of the data on the end of the buffer to the packet table. */
|
buf = rec_buffer[ii]->buffer ;
|
||||||
H5PTappend( hi->dataset, max_num - writer_offset , buf );
|
append_var_packet_table(rec_buffer[ii], buf, ds_records2, param_dataset_ids[ii]);
|
||||||
|
|
||||||
buf = hi->drb->buffer ;
|
|
||||||
/* Append all of the data at the beginning of the buffer to the packet table. */
|
|
||||||
H5PTappend( hi->dataset, local_buffer_num % max_num , buf );
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
ds_records1 = local_buffer_num - writer_num;
|
||||||
// we have 1 continous segment to write per variable
|
// we have 1 continous segment to write per variable
|
||||||
for (ii = 0; ii < parameters.size(); ii++) {
|
for (ii = 0; ii < rec_buffer.size(); ii++) {
|
||||||
HDF5_INFO * hi = parameters[ii] ;
|
//unsigned int writer_offset = writer_num % max_num ;
|
||||||
unsigned int writer_offset = writer_num % max_num ;
|
buf = rec_buffer[ii]->buffer + (writer_offset * rec_buffer[ii]->ref->attr->size) ;
|
||||||
buf = hi->drb->buffer + (writer_offset * hi->drb->ref->attr->size) ;
|
append_var_packet_table(rec_buffer[ii], buf, ds_records1, param_dataset_ids[ii]);
|
||||||
|
|
||||||
/* Append all of the data to the packet table. */
|
|
||||||
H5PTappend( hi->dataset, local_buffer_num - writer_num , buf );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writer_num = local_buffer_num ;
|
writer_num = local_buffer_num ;
|
||||||
@ -290,16 +401,13 @@ int Trick::DRHDF5::format_specific_write_data(unsigned int writer_offset __attri
|
|||||||
char *buf = 0;
|
char *buf = 0;
|
||||||
|
|
||||||
/* Loop through each parameter. */
|
/* Loop through each parameter. */
|
||||||
for (ii = 0; ii < parameters.size(); ii++) {
|
for (ii = 0; ii < rec_buffer.size(); ii++) {
|
||||||
|
|
||||||
/* Each parameters[] element contains a DataRecordBuffer class.
|
/* Each parameters[] element contains a DataRecordBuffer class.
|
||||||
* So there is a seperate DataRecordBuffer per variable.
|
* So there is a seperate DataRecordBuffer per variable.
|
||||||
* Point to the value to be recorded. */
|
* Point to the value to be recorded. */
|
||||||
HDF5_INFO * hi = parameters[ii] ;
|
buf = rec_buffer[ii]->buffer + (writer_offset * rec_buffer[ii]->ref->attr->size) ;
|
||||||
buf = hi->drb->buffer + (writer_offset * hi->drb->ref->attr->size) ;
|
append_var_packet_table(rec_buffer[ii], buf, 1, param_dataset_ids[ii]);
|
||||||
|
|
||||||
/* Append 1 value to the packet table. */
|
|
||||||
H5PTappend( hi->dataset, 1, buf );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -320,11 +428,26 @@ int Trick::DRHDF5::format_specific_shutdown() {
|
|||||||
unsigned int ii ;
|
unsigned int ii ;
|
||||||
|
|
||||||
if ( inited ) {
|
if ( inited ) {
|
||||||
for (ii = 0; ii < parameters.size(); ii++) {
|
for (ii = 0; ii < rec_buffer.size(); ii++) {
|
||||||
HDF5_INFO * hi = parameters[ii] ;
|
// Free parameter names memory
|
||||||
H5PTclose( hi->dataset );
|
free(param_names[ii]);
|
||||||
|
// Close the parameter dataset
|
||||||
|
if (param_dataset_ids[ii] != H5I_BADID) {
|
||||||
|
H5PTclose(param_dataset_ids[ii]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// Free the parameter names array
|
||||||
|
delete[] param_names;
|
||||||
|
// Set the pointer to NULL
|
||||||
|
param_names = nullptr;
|
||||||
|
// Free the dataset ids array
|
||||||
|
delete[] param_dataset_ids;
|
||||||
|
// Set the pointer to NULL
|
||||||
|
param_dataset_ids = nullptr;
|
||||||
|
|
||||||
|
// Close root group
|
||||||
H5Gclose(root_group);
|
H5Gclose(root_group);
|
||||||
|
// Close file handle
|
||||||
H5Fclose(file);
|
H5Fclose(file);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user