Fixed bitfield for hdf5

Fixed bitfield for hdf5 recording.
This commit is contained in:
Hong Chen 2025-02-05 16:54:22 -06:00
parent bd65746a34
commit dab513496e
6 changed files with 227 additions and 29 deletions

View 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()

View 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()

Binary file not shown.

View File

@ -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" )
has_dhf5 = False
if hasattr(trick, 'DRHDF5'):
has_dhf5 = True
######################################################################################################################
test_suite = "drg api"
@ -16,10 +20,18 @@ num_drgs = trick.get_num_data_record_groups()
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
dr_file_name_drg_name_tuple = (('Modified_data/dr_typesASCII.dr', 'DR_typesASCII'),
('Modified_data/dr_typesBINARY.dr', 'DR_typesBINARY'),
('Modified_data/dr_bitfASCII.dr', 'DR_bitfieldsASCII'),
('Modified_data/dr_bitfBINARY.dr', 'DR_bitfieldsBINARY'))
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'),
('Modified_data/dr_typesBINARY.dr', 'DR_typesBINARY'),
('Modified_data/dr_bitfASCII.dr', 'DR_bitfieldsASCII'),
('Modified_data/dr_bitfBINARY.dr', 'DR_bitfieldsBINARY'))
num_files = len(dr_file_name_drg_name_tuple)
for i in range(num_files):
@ -29,7 +41,10 @@ for i in range(num_files):
num_drgs = trick.get_num_data_record_groups()
# Check the result of trick.get_num_data_record_groups()
TRICK_EXPECT_EQ( num_drgs , 4 , test_suite , "num of dr groups = 4" )
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" )
# Test trick.get_data_record_group(<drg_name>) for getting the drg pointer by its name
# Check the name of the obtained drg instead of the drg pointer
@ -49,7 +64,10 @@ TRICK_EXPECT_TRUE( is_null, test_suite , "null drg by nonexistent drg name" )
is_null = False
if trick.get_data_record_group_by_idx(num_drgs+1) is None :
is_null = True
TRICK_EXPECT_TRUE( is_null, test_suite , "null drg by drg id 5" )
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" )
is_null = False
if trick.get_data_record_group_by_idx(-1) is None :

View File

@ -13,6 +13,7 @@ PROGRAMMERS:
#include "trick/command_line_protos.h"
#include "trick/memorymanager_c_intf.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) {
register_group_with_mm(this, "Trick::DRHDF5") ;
@ -140,9 +141,9 @@ int Trick::DRHDF5::format_specific_init() {
}
break;
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;
} 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;
} else {
datatype = H5T_NATIVE_UCHAR;
@ -222,6 +223,105 @@ int Trick::DRHDF5::format_specific_init() {
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
other recording methods. This write_data routine overrides the default in
@ -235,6 +335,8 @@ int Trick::DRHDF5::write_data(bool must_write) {
unsigned int num_to_write ;
unsigned int ii;
char *buf = 0;
size_t ds_records1;
size_t ds_records2;
if ( record and inited and (buffer_type == DR_No_Buffer or must_write)) {
@ -250,29 +352,28 @@ int Trick::DRHDF5::write_data(bool must_write) {
writer_num = local_buffer_num - num_to_write ;
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
if ( (writer_num % max_num) > (local_buffer_num % max_num) ) {
// we have 2 segments to write per variable
for (ii = 0; ii < rec_buffer.size(); ii++) {
unsigned int writer_offset = writer_num % max_num ;
buf = rec_buffer[ii]->buffer + (writer_offset * rec_buffer[ii]->ref->attr->size) ;
ds_records1 = max_num - writer_offset;
ds_records2 = local_buffer_num % max_num;
/* Append all of the data on the end of the buffer to the packet table. */
H5PTappend( param_dataset_ids[ii], max_num - writer_offset , buf );
// we have 2 segments to write per variable
for (ii = 0; ii < rec_buffer.size(); ii++) {
//unsigned int writer_offset = writer_num % max_num ;
buf = rec_buffer[ii]->buffer + (writer_offset * rec_buffer[ii]->ref->attr->size) ;
append_var_packet_table(rec_buffer[ii], buf, ds_records1, param_dataset_ids[ii]);
buf = rec_buffer[ii]->buffer ;
/* Append all of the data at the beginning of the buffer to the packet table. */
H5PTappend( param_dataset_ids[ii], local_buffer_num % max_num , buf );
}
buf = rec_buffer[ii]->buffer ;
append_var_packet_table(rec_buffer[ii], buf, ds_records2, param_dataset_ids[ii]);
}
} else {
// we have 1 continous segment to write per variable
for (ii = 0; ii < rec_buffer.size(); ii++) {
unsigned int writer_offset = writer_num % max_num ;
buf = rec_buffer[ii]->buffer + (writer_offset * rec_buffer[ii]->ref->attr->size) ;
/* Append all of the data to the packet table. */
H5PTappend( param_dataset_ids[ii], local_buffer_num - writer_num , buf );
ds_records1 = local_buffer_num - writer_num;
// we have 1 continous segment to write per variable
for (ii = 0; ii < rec_buffer.size(); ii++) {
//unsigned int writer_offset = writer_num % max_num ;
buf = rec_buffer[ii]->buffer + (writer_offset * rec_buffer[ii]->ref->attr->size) ;
append_var_packet_table(rec_buffer[ii], buf, ds_records1, param_dataset_ids[ii]);
}
}
writer_num = local_buffer_num ;
@ -306,9 +407,7 @@ int Trick::DRHDF5::format_specific_write_data(unsigned int writer_offset __attri
* So there is a seperate DataRecordBuffer per variable.
* Point to the value to be recorded. */
buf = rec_buffer[ii]->buffer + (writer_offset * rec_buffer[ii]->ref->attr->size) ;
/* Append 1 value to the packet table. */
H5PTappend( param_dataset_ids[ii], 1, buf );
append_var_packet_table(rec_buffer[ii], buf, 1, param_dataset_ids[ii]);
}
#endif