# Dataset Insert Vector of Compound Type

**URL:** <https://forum.hdfgroup.org/t/dataset-insert-vector-of-compound-type/9027>\
**Category:** HDF5 Library\
**Created:** [October 7, 2021, 3:02am UTC](https://forum.hdfgroup.org/t/dataset-insert-vector-of-compound-type/9027 "2021-10-07T03:02:37Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![nathan.i.katz.ctr](https://forum.hdfgroup.org/letter_avatar_proxy/v4/letter/n/5f8ce5/32.png) [@nathan.i.katz.ctr](https://forum.hdfgroup.org/u/nathan.i.katz.ctr)\
**Post date:** [October 7, 2021, 3:02am UTC](https://forum.hdfgroup.org/t/dataset-insert-vector-of-compound-type/9027/1 "2021-10-07T03:02:37Z")

</div>

Using the C HDF5 library, I’m trying to use a prepopulated vector and insert it into my HDF5 file. I would like to not have to recopy the data and just add the vector I have. Is there any way I can get H5Tarray\_create to work in my case? I want to use H5Tarray because of it’s easier to debug in HDFView (and looks better). H5Tvlen\_create does work, but doesn’t get the desired effect in HDFView.

```
struct Key {
	float code, value;
};

struct Instruction {
	float timestamp;
	Key *keys;
};

struct v_Instruction {
	float timestamp;
	hvl_t keys;
};

//---

std::vector<Key> keys(2);
keys[0].code = 1;
keys[0].value = 123;
keys[1].code = 2;
keys[1].value = 234;

const hsize_t arr_dims[] = {keys.size()};

hid_t compoundKey = H5Tcreate(H5T_COMPOUND, sizeof(Key));
H5Tinsert(compoundKey, "Code", HOFFSET(Key, code), H5T_NATIVE_FLOAT);
H5Tinsert(compoundKey, "Value", HOFFSET(Key, value), H5T_NATIVE_FLOAT);

//
// Wanted: Array Method
//
hid_t key_array = H5Tarray_create(compoundKey, 1, arr_dims);
size_t s_Instruction = sizeof(Instruction::timestamp) + sizeof(Key) * keys.size();
hid_t compoundInstr = H5Tcreate(H5T_COMPOUND, s_Instruction);
H5Tinsert(compoundInstr, "timestamp", 0, H5T_NATIVE_FLOAT);
H5Tinsert(compoundInstr, "Keys", sizeof(Instruction::timestamp), key_array);

//Create Dataset
//Write Data
Instruction test;
test.timestamp = 1;
test.keys = &keys.front();
H5Dwrite(dset, compoundInstr, H5S_ALL, H5S_ALL, H5P_DEFAULT, &test); // Doesn't set data correctly

//
// V Len Method
//
hid_t vLen_key = H5Tvlen_create(compoundKey);
compoundInstr = H5Tcreate(H5T_COMPOUND, sizeof(v_Instruction));
H5Tinsert(compoundInstr, "timestamp", HOFFSET(v_Instruction, timestamp), H5T_NATIVE_FLOAT);
H5Tinsert(compoundInstr, "Keys", HOFFSET(v_Instruction, keys), vLen_key);

//Create Dataset
//Write Data
v_Instruction v_test;
v_test.timestamp = 1;
v_test.keys.len = keys.size();
v_test.keys.p = &keys.front();
H5Dwrite(dset, compoundInstr, H5S_ALL, H5S_ALL, H5P_DEFAULT, &v_test);
```

---

<div class="post-metadata">

**Author:** ![steven](https://forum.hdfgroup.org/user_avatar/forum.hdfgroup.org/steven/32/117_2.png) [@steven](https://forum.hdfgroup.org/u/steven)\
**Post date:** [October 7, 2021, 4:19am UTC](https://forum.hdfgroup.org/t/dataset-insert-vector-of-compound-type/9027/2 "2021-10-07T04:19:16Z")

</div>

H5CPP implements `read|write` with zero copy for non-strings, and comes with an LLVM based introspection tool, all descriptors (except `h5::pt_t<T>` packet table ) are binary compatible with HDF5 CAPI allowing you to interchange C and C++ calls withing C++ code.  
the following excerpt is from [the github examples](https://github.com/steven-varga/h5cpp/tree/master/examples/compound). Presentation [slides are here.](http://sandbox.h5cpp.org/presentations/)

```auto
#include "struct.h"
#include <h5cpp/core>
	#include "generated.h"
#include <h5cpp/io>

int main(){
  h5::fd_t fd = h5::create("example.h5",H5F_ACC_TRUNC);
	
  std::vector<sn::example::Record> vec = h5::utils::get_test_data<sn::example::Record>(20);
  // this part is zero copy, reads data size out from `vec`
  h5::write(fd, "some dataset, somwhere", vec, h5::chunk{20} | h5::gzip{9});
  // more efficient way to do it is to pre-create dataset:  
  auto ds2 = h5::create<sn::example::Record>(fd, "dataset", h5::current_dims{20});
  // you always can pass typed pointers as well, just specify the size:
  h5::write(ds2, vec.data(), h5::count{20}); 
// <- this is not recommended with vectors, there is no performance difference between the two syntax;  
// instead use it for typed pointers, or for non-STL like containers
}
// RAII will close all resources when leaving code block

```

The HDF5 type descriptors are generated with `h5cpp` [introspection tool](http://sandbox.h5cpp.org/compiler/).  
best: steve

---

<div class="post-metadata">

**Author:** ![nathan.i.katz.ctr](https://forum.hdfgroup.org/letter_avatar_proxy/v4/letter/n/5f8ce5/32.png) [@nathan.i.katz.ctr](https://forum.hdfgroup.org/u/nathan.i.katz.ctr)\
**Post date:** [October 7, 2021, 5:37pm UTC](https://forum.hdfgroup.org/t/dataset-insert-vector-of-compound-type/9027/3 "2021-10-07T17:37:47Z")

</div>

We are unable to change from the HDF5 C Library, so while this could be a solution it isn’t a solution for me.

My question is how to get `H5Tarray_create` to work without using `Key keys[#]`. I tried (and failed) using `std::array`, which on the backend uses the c-style arrays. The problem with `[]` is that I would have to go through it to assign all values from my `std::vector`.

I would like for more information sake on why my way won’t work or if there is a way to do this.

---

<div class="post-metadata">

**Author:** ![steven](https://forum.hdfgroup.org/user_avatar/forum.hdfgroup.org/steven/32/117_2.png) [@steven](https://forum.hdfgroup.org/u/steven)\
**Post date:** [October 7, 2021, 6:07pm UTC](https://forum.hdfgroup.org/t/dataset-insert-vector-of-compound-type/9027/4 "2021-10-07T18:07:21Z")

</div>

From your response it appears you don’t understand what binary compatibility means, so I elaborate:

- you can interact with your CAPI calls:
  - pass HDF5 CAPI identifier to H5CPP identifier: They are the same after the template processor is done
  - pass HCPP identifier to HDF5 CAPI calls: They are the same after the template processor done

- it is guaranteed identity between the C code compiled with C++17 compiler and H5CPP templates
- AFAIK there is no other HDF5 CAPI

This meta-programming template library was crafted for the very purpose to NOT TO REPLACE the HDF5 CAPI but to enhance it with features that C language can’t provide; and exists in C++17.

---

<div class="post-metadata">

**Author:** ![gheber](https://forum.hdfgroup.org/user_avatar/forum.hdfgroup.org/gheber/32/1919_2.png) [@gheber](https://forum.hdfgroup.org/u/gheber)\
**Post date:** [October 11, 2021, 9:07pm UTC](https://forum.hdfgroup.org/t/dataset-insert-vector-of-compound-type/9027/5 "2021-10-11T21:07:37Z")

</div>

Nathan, the fixed-size array version (`H5T_ARRAY`) works only if all instructions have  
the same key count.

```auto
struct Instruction {
	float timestamp;
	Key keys[MAX_KEYS];
};

```

Is there such a maximum key count and how many key counts do  
you have on average? You could just fill in default keys and use compression  
to trim the overhead, at least in the file.

G.

---

<div class="post-metadata">

**Author:** ![nathan.i.katz.ctr](https://forum.hdfgroup.org/letter_avatar_proxy/v4/letter/n/5f8ce5/32.png) [@nathan.i.katz.ctr](https://forum.hdfgroup.org/u/nathan.i.katz.ctr)\
**Post date:** [October 12, 2021, 1:54pm UTC](https://forum.hdfgroup.org/t/dataset-insert-vector-of-compound-type/9027/6 "2021-10-12T13:54:36Z")

</div>

When I pass my std::vector of my structure for recording it is always the same size.

`Key keys[MAX_KEYS]` does work, but I have to copy each of my structures to the c-style array. I was hoping for a way to avoid copying the structures. When I tried `Key &keys[MAX_KEYS]` (to get a refence so I didn’t have to copy) and it crashed.

---

<div class="post-metadata">

**Author:** ![gheber](https://forum.hdfgroup.org/user_avatar/forum.hdfgroup.org/gheber/32/1919_2.png) [@gheber](https://forum.hdfgroup.org/u/gheber)\
**Post date:** [October 12, 2021, 3:58pm UTC](https://forum.hdfgroup.org/t/dataset-insert-vector-of-compound-type/9027/7 "2021-10-12T15:58:41Z")

</div>

The storage layouts are fundamentally different:

```auto
struct Instruction {
	float timestamp;
	Key keys[MAX_KEYS];
};

```

is contiguous in memory.

```auto
struct Instruction {
	float timestamp;
	Key* keys;
};

```

is not, even if the `keys` arrays have all the same size.

`v_Instruction` and initializing the pointers in `hvl_t` is perhaps your best option.

G.
