Question about compound type

Hi,

     I am new to compound type and am learning it using the following as a reference

http://www.hdfgroup.org/ftp/HDF5/examples/examples-by-api/hdf5-examples/1_8/C/H5T/h5ex_t_cmpd.c

     I did build an ran the example and it produce the expected result.

     Using the above, I tried creating my own compound type; a vector of x,y,z but my data is always '0'

     I have include the source code and the h5dump output in this posting.

     I'd like to know where I have gone wrong.

Kind regards

== h5dump of file ==
HDF5 "vertex_compound.h5" {
GROUP "/" {
    DATASET "vertices" {
       DATATYPE H5T_COMPOUND {
          H5T_IEEE_F32LE "x";
          H5T_IEEE_F32LE "y";
          H5T_IEEE_F32LE "z";
       }
       DATASPACE SIMPLE { ( 4 ) / ( 4 ) }
       DATA {
       (0): {
             0,
             0
          },
       (1): {
             0,
             0
          },
       (2): {
             0,
             0
          },
       (3): {
             0,
             0
          }
       }
    }
}

== source code ==

#include "hdf5.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

const char dataset_name[] = "vertices";
const hsize_t DIM0=4;
const size_t RANK_OUT = 1;
const size_t NX_SUB = 1; // Number of vertices to read in
const size_t NX = 1; // Number of vertices to read in
const size_t NY = 3; // Number of scalar e.g. x,y,z i.e. 3

typedef struct {
     float x;
     float y;
     float z;
} v3f_t; /* Compound type */

void write_file(const char* filename)
{
     hid_t file, filetype, memtype, space, dset;
     /* Handles */
     herr_t status;
     hsize_t dims[1] = {DIM0};
     v3f_t wdata[DIM0]; /* Write buffer */

     /*
      * Initialize data.
      */
     wdata[0].x = 0.0;
     wdata[0].y = 1.0;
     wdata[0].z = 2.0;

     wdata[1].x = 3.0;
     wdata[1].y = 4.0;
     wdata[1].z = 5.0;

     wdata[2].x = 6.0;
     wdata[2].y = 7.0;
     wdata[2].z = 8.0;

     wdata[3].x = 9.0;
     wdata[3].y = 10.0;
     wdata[3].z = 11.0;

     /*
      * Create a new file using the default properties.
      */
     file = H5Fcreate (filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

     /*
      * Create the compound datatype for memory.
      */
     memtype = H5Tcreate (H5T_COMPOUND, sizeof (v3f_t));
     status = H5Tinsert (memtype, "x coordinate",
                         HOFFSET (v3f_t, x), H5T_NATIVE_FLOAT);
     status = H5Tinsert (memtype, "y coordinate",
                         HOFFSET (v3f_t, y), H5T_NATIVE_FLOAT);
     status = H5Tinsert (memtype, "z coordinate",
                         HOFFSET (v3f_t, z), H5T_NATIVE_FLOAT);

     /*
      * Create the compound datatype for the file. Because the standard
      * types we are using for the file may have different sizes than
      * the corresponding native types, we must manually calculate the
      * offset of each member.
      */
     filetype = H5Tcreate (H5T_COMPOUND, 4 + 4 + 4);
     status = H5Tinsert (filetype, "x", 0, H5T_IEEE_F32LE);
     status = H5Tinsert (filetype, "y", 4, H5T_IEEE_F32LE);
     status = H5Tinsert (filetype, "z", 8, H5T_IEEE_F32LE);

     /*
      * Create dataspace. Setting maximum size to NULL sets the maximum
      * size to be the current size.
      */
     space = H5Screate_simple (1, dims, NULL);

     /*
      * Create the dataset and write the compound data to it.
      */
     dset = H5Dcreate (file, dataset_name, filetype, space, H5P_DEFAULT, H5P_DEFAULT,
                       H5P_DEFAULT);
     status = H5Dwrite (dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);

     /*
      * Close and release resources.
      */
     status = H5Dclose (dset);
     status = H5Sclose (space);
     status = H5Tclose (filetype);
     status = H5Fclose (file);

}
int main (void)
{
     char filename[] = "vertex_compound.h5";
     write_file(filename);

     return 0;
}

Cheers

···

--
Nicholas Yue
Graphics - RenderMan, Visualization, OpenGL, HDF5
Custom Dev - C++ porting, OSX, Linux, Windows
http://au.linkedin.com/in/nicholasyue

Nick, how are you? The problem, and I've made that mistake many times
myself (usually typo), is the mismatch in the component names of your compounds.
Your memory type uses "x coordinate", "y coordinate", "z coordinate".
Your file type uses "x", "y", "z".
H5D[read,write] match components by name. In your case, there's
a total mismatch. Try matching just one, i.e., "x coordinate" -> "x"
and the first component should be written as expected.

Best, G.

···

-----Original Message-----
From: Hdf-forum [mailto:hdf-forum-bounces@lists.hdfgroup.org] On Behalf Of Nicholas Yue
Sent: Tuesday, October 22, 2013 11:46 PM
To: HDF Users Discussion List
Subject: [Hdf-forum] Question about compound type

Hi,

     I am new to compound type and am learning it using the following as a reference

http://www.hdfgroup.org/ftp/HDF5/examples/examples-by-api/hdf5-examples/1_8/C/H5T/h5ex_t_cmpd.c

     I did build an ran the example and it produce the expected result.

     Using the above, I tried creating my own compound type; a vector of x,y,z but my data is always '0'

     I have include the source code and the h5dump output in this posting.

     I'd like to know where I have gone wrong.

Kind regards

== h5dump of file ==
HDF5 "vertex_compound.h5" {
GROUP "/" {
    DATASET "vertices" {
       DATATYPE H5T_COMPOUND {
          H5T_IEEE_F32LE "x";
          H5T_IEEE_F32LE "y";
          H5T_IEEE_F32LE "z";
       }
       DATASPACE SIMPLE { ( 4 ) / ( 4 ) }
       DATA {
       (0): {
             0,
             0,
             0
          },
       (1): {
             0,
             0,
             0
          },
       (2): {
             0,
             0,
             0
          },
       (3): {
             0,
             0,
             0
          }
       }
    }
}
}

== source code ==

#include "hdf5.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

const char dataset_name[] = "vertices";
const hsize_t DIM0=4;
const size_t RANK_OUT = 1;
const size_t NX_SUB = 1; // Number of vertices to read in const size_t NX = 1; // Number of vertices to read in const size_t NY = 3; // Number of scalar e.g. x,y,z i.e. 3

typedef struct {
     float x;
     float y;
     float z;
} v3f_t; /* Compound type */

void write_file(const char* filename)
{
     hid_t file, filetype, memtype, space, dset;
     /* Handles */
     herr_t status;
     hsize_t dims[1] = {DIM0};
     v3f_t wdata[DIM0]; /* Write buffer */

     /*
      * Initialize data.
      */
     wdata[0].x = 0.0;
     wdata[0].y = 1.0;
     wdata[0].z = 2.0;

     wdata[1].x = 3.0;
     wdata[1].y = 4.0;
     wdata[1].z = 5.0;

     wdata[2].x = 6.0;
     wdata[2].y = 7.0;
     wdata[2].z = 8.0;

     wdata[3].x = 9.0;
     wdata[3].y = 10.0;
     wdata[3].z = 11.0;

     /*
      * Create a new file using the default properties.
      */
     file = H5Fcreate (filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

     /*
      * Create the compound datatype for memory.
      */
     memtype = H5Tcreate (H5T_COMPOUND, sizeof (v3f_t));
     status = H5Tinsert (memtype, "x coordinate",
                         HOFFSET (v3f_t, x), H5T_NATIVE_FLOAT);
     status = H5Tinsert (memtype, "y coordinate",
                         HOFFSET (v3f_t, y), H5T_NATIVE_FLOAT);
     status = H5Tinsert (memtype, "z coordinate",
                         HOFFSET (v3f_t, z), H5T_NATIVE_FLOAT);

     /*
      * Create the compound datatype for the file. Because the standard
      * types we are using for the file may have different sizes than
      * the corresponding native types, we must manually calculate the
      * offset of each member.
      */
     filetype = H5Tcreate (H5T_COMPOUND, 4 + 4 + 4);
     status = H5Tinsert (filetype, "x", 0, H5T_IEEE_F32LE);
     status = H5Tinsert (filetype, "y", 4, H5T_IEEE_F32LE);
     status = H5Tinsert (filetype, "z", 8, H5T_IEEE_F32LE);

     /*
      * Create dataspace. Setting maximum size to NULL sets the maximum
      * size to be the current size.
      */
     space = H5Screate_simple (1, dims, NULL);

     /*
      * Create the dataset and write the compound data to it.
      */
     dset = H5Dcreate (file, dataset_name, filetype, space, H5P_DEFAULT, H5P_DEFAULT,
                       H5P_DEFAULT);
     status = H5Dwrite (dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);

     /*
      * Close and release resources.
      */
     status = H5Dclose (dset);
     status = H5Sclose (space);
     status = H5Tclose (filetype);
     status = H5Fclose (file);

}
int main (void)
{
     char filename[] = "vertex_compound.h5";
     write_file(filename);

     return 0;
}

Cheers

--
Nicholas Yue
Graphics - RenderMan, Visualization, OpenGL, HDF5 Custom Dev - C++ porting, OSX, Linux, Windows http://au.linkedin.com/in/nicholasyue
https://vimeo.com/channels/naiadtools

_______________________________________________
Hdf-forum is for HDF software users discussion.
Hdf-forum@lists.hdfgroup.org
http://mail.lists.hdfgroup.org/mailman/listinfo/hdf-forum_lists.hdfgroup.org

Hi Gerd,

     Thanks for that.

     I have fixed that and it is now working well.

Cheers

···

On 23/10/13 11:06 PM, Gerd Heber wrote:

Nick, how are you? The problem, and I've made that mistake many times
myself (usually typo), is the mismatch in the component names of your compounds.
Your memory type uses "x coordinate", "y coordinate", "z coordinate".
Your file type uses "x", "y", "z".
H5D[read,write] match components by name. In your case, there's
a total mismatch. Try matching just one, i.e., "x coordinate" -> "x"
and the first component should be written as expected.

--
Nicholas Yue
Graphics - RenderMan, Visualization, OpenGL, HDF5
Custom Dev - C++ porting, OSX, Linux, Windows
http://au.linkedin.com/in/nicholasyue