/* * Copyright (C) 1998 NCSA * All rights reserved. * * Programmer: Robb Matzke <matzke@llnl.gov> * Friday, January 23, 1998 */ #include <assert.h> #include <hdf5.h> #include <stdio.h> #include <stdlib.h> #include <string.h> /* The first dataset */ typedef struct s1_t { int a; int b; int c; int d; int e; } s1_t; /* The second dataset (same as first) */ typedef s1_t s2_t; /* The third dataset (reversed fields of s1) */ typedef struct s3_t { int e; int d; int c; int b; int a; } s3_t; /* The fourth dataset (a subset of s1) */ typedef struct s4_t { int b; int d; } s4_t; /* The fifth dataset (a superset of s1) */ typedef struct s5_t { int pre; int a; int b; int mid1; int c; int mid2; int d; int e; int post; } s5_t; #if 1 # define NX 100 # define NY 2000 #else # define NX 12 # define NY 9 #endif /*------------------------------------------------------------------------- * Function: main * * Purpose: Creates a simple dataset of a compound type and then reads * it back. The dataset is read back in various ways to * exercise the I/O pipeline and compound type conversion. * * Return: Success: 0 * * Failure: 1 * * Programmer: Robb Matzke * Friday, January 23, 1998 * * Modifications: * *------------------------------------------------------------------------- */ int main (void) { /* First dataset */ static s1_t s1[NX*NY]; hid_t s1_tid; /* Second dataset */ static s2_t s2[NX*NY]; hid_t s2_tid; /* Third dataset */ static s3_t s3[NX*NY]; hid_t s3_tid; /* Fourth dataset */ static s4_t s4[NX*NY]; hid_t s4_tid; /* Fifth dataset */ static s5_t s5[NX*NY]; hid_t s5_tid; /* Sixth dataset */ /* Seventh dataset */ hid_t s7_sid; /* Eighth dataset */ s1_t *s8 = NULL; hid_t s8_f_sid; /*file data space */ hid_t s8_m_sid; /*memory data space */ /* Ninth dataset */ /* Tenth dataset */ /* Eleventh dataset */ s5_t *s11 = NULL; /* Other variables */ int i, j, ndims; hid_t file, dataset, space; herr_t status; static size_t dim[] = {NX, NY}; int f_offset[2]; /*offset of hyperslab in file */ size_t h_size[2]; /*size of hyperslab */ size_t h_sample[2]; /*hyperslab sampling */ /* Create the file */ file = H5Fcreate ("cmpd_dset.h5", H5ACC_OVERWRITE, H5C_DEFAULT, H5C_DEFAULT); assert (file>=0); /* Create the data space */ space = H5Pcreate_simple (2, dim, NULL); assert (space>=0); /* *###################################################################### * STEP 1: Save the original dataset natively. */ printf ("\ STEP 1: Initialize dataset `s1' and store it on disk in native order.\n"); fflush (stdout); /* Initialize the dataset */ for (i=0; i<NX*NY; i++) { s1[i].a = 5*i+0; s1[i].b = 2000*2*i; s1[i].c = 5*i+2; s1[i].d = 2001+2*i; s1[i].e = 5*i+4; } /* Create the memory data type */ s1_tid = H5Tcreate (H5T_COMPOUND, sizeof(s1_t)); H5Tinsert (s1_tid, "a", HPOFFSET(s1,a), H5T_NATIVE_INT); H5Tinsert (s1_tid, "b", HPOFFSET(s1,b), H5T_NATIVE_INT); H5Tinsert (s1_tid, "c", HPOFFSET(s1,c), H5T_NATIVE_INT); H5Tinsert (s1_tid, "d", HPOFFSET(s1,d), H5T_NATIVE_INT); H5Tinsert (s1_tid, "e", HPOFFSET(s1,e), H5T_NATIVE_INT); assert (s1_tid>=0); /* Create the dataset */ dataset = H5Dcreate (file, "s1", s1_tid, space, H5C_DEFAULT); assert (dataset>=0); /* Write the data */ status = H5Dwrite (dataset, s1_tid, H5P_ALL, H5P_ALL, H5C_DEFAULT, s1); assert (status>=0); /* *###################################################################### * STEP 2: We create a new type ID for the second dataset even though * it's the same as the first just to test things better, but * in fact, we could have used s1_tid. */ printf ("\ STEP 2: Read the dataset from disk into a new memory buffer which has the\n\ same data type and space. This will be the typical case.\n"); fflush (stdout); /* Create a data type for s2 */ s2_tid = H5Tcreate (H5T_COMPOUND, sizeof(s2_t)); H5Tinsert (s2_tid, "a", HPOFFSET(s2,a), H5T_NATIVE_INT); H5Tinsert (s2_tid, "b", HPOFFSET(s2,b), H5T_NATIVE_INT); H5Tinsert (s2_tid, "c", HPOFFSET(s2,c), H5T_NATIVE_INT); H5Tinsert (s2_tid, "d", HPOFFSET(s2,d), H5T_NATIVE_INT); H5Tinsert (s2_tid, "e", HPOFFSET(s2,e), H5T_NATIVE_INT); assert (s2_tid>=0); /* Read the data */ status = H5Dread (dataset, s2_tid, H5P_ALL, H5P_ALL, H5C_DEFAULT, s2); assert (status>=0); /* Compare s2 with s1. They should be the same */ for (i=0; i<NX*NY; i++) { assert (s1[i].a==s2[i].a); assert (s1[i].b==s2[i].b); assert (s1[i].c==s2[i].c); assert (s1[i].d==s2[i].d); assert (s1[i].e==s2[i].e); } /* *###################################################################### * STEP 3: Read the dataset back into a third memory buffer. This buffer * has the same data space but the data type is different: the * data type is a struct whose members are in the opposite order. */ printf ("\ STEP 3: Read the dataset again with members in a different order.\n"); fflush (stdout); /* Create a data type for s3 */ s3_tid = H5Tcreate (H5T_COMPOUND, sizeof(s3_t)); H5Tinsert (s3_tid, "a", HPOFFSET(s3,a), H5T_NATIVE_INT); H5Tinsert (s3_tid, "b", HPOFFSET(s3,b), H5T_NATIVE_INT); H5Tinsert (s3_tid, "c", HPOFFSET(s3,c), H5T_NATIVE_INT); H5Tinsert (s3_tid, "d", HPOFFSET(s3,d), H5T_NATIVE_INT); H5Tinsert (s3_tid, "e", HPOFFSET(s3,e), H5T_NATIVE_INT); assert (s3_tid>=0); /* Read the data */ status = H5Dread (dataset, s3_tid, H5P_ALL, H5P_ALL, H5C_DEFAULT, s3); assert (status>=0); /* Compare s3 with s1. They should be the same */ for (i=0; i<NX*NY; i++) { assert (s1[i].a==s3[i].a); assert (s1[i].b==s3[i].b); assert (s1[i].c==s3[i].c); assert (s1[i].d==s3[i].d); assert (s1[i].e==s3[i].e); } /* *###################################################################### * STEP 4: Read a subset of the members. Of the <a,b,c,d,e> members * stored on disk we'll read <b,d>. */ printf ("\ STEP 4: Read a subset of the members.\n"); fflush (stdout); /* Create a datatype for s4 */ s4_tid = H5Tcreate (H5T_COMPOUND, sizeof(s4_t)); H5Tinsert (s4_tid, "b", HPOFFSET(s4,b), H5T_NATIVE_INT); H5Tinsert (s4_tid, "d", HPOFFSET(s4,d), H5T_NATIVE_INT); assert (s4_tid>=0); /* Read the data */ status = H5Dread (dataset, s4_tid, H5P_ALL, H5P_ALL, H5C_DEFAULT, s4); assert (status>=0); /* Compare s4 with s1 */ for (i=0; i<NX*NY; i++) { assert (s1[i].b==s4[i].b); assert (s1[i].d==s4[i].d); } /* *###################################################################### * STEP 5: Read all the members into a struct which has other members * which have already been initialized. */ printf ("\ STEP 5: Read members into a superset which is partially initialized.\n"); fflush (stdout); /* Initialize some members */ for (i=0; i<NX*NY; i++) { s5[i].pre = 1000+4*i; s5[i].mid1 = 1001+4*i; s5[i].mid2 = 1002+4*i; s5[i].post = 1003+4*i; } /* Create a data type for s5 */ s5_tid = H5Tcreate (H5T_COMPOUND, sizeof(s5_t)); H5Tinsert (s5_tid, "a", HPOFFSET(s5,a), H5T_NATIVE_INT); H5Tinsert (s5_tid, "b", HPOFFSET(s5,b), H5T_NATIVE_INT); H5Tinsert (s5_tid, "c", HPOFFSET(s5,c), H5T_NATIVE_INT); H5Tinsert (s5_tid, "d", HPOFFSET(s5,d), H5T_NATIVE_INT); H5Tinsert (s5_tid, "e", HPOFFSET(s5,e), H5T_NATIVE_INT); assert (s5_tid>=0); /* Read the data */ status = H5Dread (dataset, s5_tid, H5P_ALL, H5P_ALL, H5C_DEFAULT, s5); assert (status>=0); /* Check that the data was read properly */ for (i=0; i<NX*NY; i++) { assert (s1[i].a==s5[i].a); assert (s1[i].b==s5[i].b); assert (s1[i].c==s5[i].c); assert (s1[i].d==s5[i].d); assert (s1[i].e==s5[i].e); } /* Check that no previous values were clobbered */ for (i=0; i<NX*NY; i++) { assert (s5[i].pre == 1000+4*i); assert (s5[i].mid1 == 1001+4*i); assert (s5[i].mid2 == 1002+4*i); assert (s5[i].post == 1003+4*i); } /* *###################################################################### * STEP 6: Update fields `b' and `d' on the file leaving the other * fields unchanged. This tests member alignment and background * buffers. */ printf ("\ STEP 6: Update fields `b' and `d' on the file, leaving the other fields\n\ unchanged.\n"); fflush (stdout); /* Initialize `s4' with new values */ for (i=0; i<NX*NY; i++) { s4[i].b = 5*i+1; s4[i].d = 5*i+3; } /* Write the data to file */ status = H5Dwrite (dataset, s4_tid, H5P_ALL, H5P_ALL, H5C_DEFAULT, s4); assert (status>=0); /* Read the data back */ status = H5Dread (dataset, s1_tid, H5P_ALL, H5P_ALL, H5C_DEFAULT, s1); assert (status>=0); /* Compare */ for (i=0; i<NX*NY; i++) { assert (s1[i].a == 5*i+0); assert (s1[i].b == 5*i+1); assert (s1[i].c == 5*i+2); assert (s1[i].d == 5*i+3); assert (s1[i].e == 5*i+4); } /* *###################################################################### * STEP 7. Read the original dataset with an explicit data space. Even * though these data spaces are equal it tests a different part of the * library. */ printf ("\ STEP 7: Reading original dataset with explicit data space.\n"); fflush (stdout); /* Create the data space */ s7_sid = H5Pcreate_simple (2, dim, NULL); assert (s7_sid>=0); /* Read the dataset */ status = H5Dread (dataset, s2_tid, s7_sid, H5P_ALL, H5C_DEFAULT, s2); assert (status>=0); /* Compare */ for (i=0; i<NX*NY; i++) { assert (s2[i].a == s1[i].a); assert (s2[i].b == s1[i].b); assert (s2[i].c == s1[i].c); assert (s2[i].d == s1[i].d); assert (s2[i].e == s1[i].e); } /* *###################################################################### * STEP 8. Read a hyperslab of the file into a complete array in memory. * The hyperslab is the middle third of the array. */ printf ("\ STEP 8: Read middle third hyperslab into memory array.\n"); fflush (stdout); /* Create the file data space */ s8_f_sid = H5Dget_space (dataset); assert (s8_f_sid>=0); f_offset[0] = NX/3; f_offset[1] = NY/3; h_size[0] = 2*NX/3 - f_offset[0]; h_size[1] = 2*NY/3 - f_offset[1]; h_sample[0] = 1; h_sample[1] = 1; status = H5Pset_hyperslab (s8_f_sid, f_offset, h_size, h_sample); assert (status>=0); /* Create memory data space */ s8_m_sid = H5Pcreate_simple (2, h_size, NULL); assert (s8_m_sid>=0); /* Read the dataset */ s8 = calloc (h_size[0]*h_size[1], sizeof(s1_t)); assert (s8); status = H5Dread (dataset, s1_tid, s8_m_sid, s8_f_sid, H5C_DEFAULT, s8); assert (status>=0); /* Compare */ for (i=0; i<h_size[0]; i++) { for (j=0; j<h_size[1]; j++) { s1_t *ps1 = s1 + (f_offset[0]+i)*NY + f_offset[1] + j; s1_t *ps8 = s8 + i*h_size[1] + j; assert (ps8->a == ps1->a); assert (ps8->b == ps1->b); assert (ps8->c == ps1->c); assert (ps8->d == ps1->d); assert (ps8->e == ps1->e); } } free (s8); s8 = NULL; /* *###################################################################### * STEP 9. Read a hyperslab of the file into a hyperslab of memory. The * part of memory not read is already initialized and must not change. */ printf ("\ STEP 9: Read middle third of hyperslab into middle third of memory array.\n"); fflush (stdout); /* Initialize with some bit pattern */ memset (s2, 0xFF, NX*NY*sizeof(s2_t)); /* Read the hyperslab */ status = H5Dread (dataset, s2_tid, s8_f_sid, s8_f_sid, H5C_DEFAULT, s2); assert (status>=0); /* Compare */ for (i=0; i<NX; i++) { for (j=0; j<NY; j++) { s1_t *ps1 = s1 + i*NY + j; s2_t *ps2 = s2 + i*NY + j; if (i>=f_offset[0] && i<f_offset[0]+h_size[0] && j>=f_offset[1] && j<f_offset[1]+h_size[1]) { assert (ps2->a == ps1->a); assert (ps2->b == ps1->b); assert (ps2->c == ps1->c); assert (ps2->d == ps1->d); assert (ps2->e == ps1->e); } else { assert (ps2->a == -1); assert (ps2->b == -1); assert (ps2->c == -1); assert (ps2->d == -1); assert (ps2->e == -1); } } } /* *###################################################################### * STEP 10. Same as step 9 except the memory array contains some members * which are already initialized, like step 5. */ printf ("\ STEP 10: Read middle third of hyperslab into middle third of memory array\n\ where some of the struct members are already initialized.\n"); fflush (stdout); /* Initialize with some bit pattern */ memset (s5, 0xFF, NX*NY*sizeof(s5_t)); /* Read the hyperslab */ status = H5Dread (dataset, s5_tid, s8_f_sid, s8_f_sid, H5C_DEFAULT, s5); assert (status>=0); /* Compare */ for (i=0; i<NX; i++) { for (j=0; j<NY; j++) { s1_t *ps1 = s1 + i*NY + j; s5_t *ps5 = s5 + i*NY + j; if (i>=f_offset[0] && i<f_offset[0]+h_size[0] && j>=f_offset[1] && j<f_offset[1]+h_size[1]) { assert (ps5->pre == -1); assert (ps5->a == ps1->a); assert (ps5->b == ps1->b); assert (ps5->mid1 == -1); assert (ps5->c == ps1->c); assert (ps5->mid2 == -1); assert (ps5->d == ps1->d); assert (ps5->e == ps1->e); assert (ps5->post == -1); } else { assert (ps5->pre == -1); assert (ps5->a == -1); assert (ps5->b == -1); assert (ps5->mid1 == -1); assert (ps5->c == -1); assert (ps5->mid2 == -1); assert (ps5->d == -1); assert (ps5->e == -1); assert (ps5->post == -1); } } } /* *###################################################################### * Step 11: Write an array into the middle third of the dataset * initializeing only members `b' and `d' to -1. */ printf ("\ STEP 11: Write an array back to the middle third of the dataset to\n\ initialize the `b' and `d' members to -1.\n"); fflush (stdout); /* Create the memory array and initialize all fields to zero */ ndims = H5Pget_hyperslab (s8_f_sid, f_offset, h_size, h_sample); assert (ndims==2); s11 = malloc (h_size[0]*h_size[1]*sizeof(s4_t)); assert (s11); memset (s11, 0xff, h_size[0]*h_size[1]*sizeof(s4_t)); /* Write to disk */ status = H5Dwrite (dataset, s4_tid, s8_m_sid, s8_f_sid, H5C_DEFAULT, s11); assert (status>=0); /* Read the whole thing */ status = H5Dread (dataset, s1_tid, H5P_ALL, H5P_ALL, H5C_DEFAULT, s1); assert (status>=0); /* Compare */ for (i=0; i<NX; i++) { for (j=0; j<NY; j++) { s1_t *ps1 = s1 + i*NY + j; assert (ps1->a == 5*(i*NY+j)+0); assert (ps1->c == 5*(i*NY+j)+2); assert (ps1->e == 5*(i*NY+j)+4); if (i>=f_offset[0] && i<f_offset[0]+h_size[0] && j>=f_offset[1] && j<f_offset[1]+h_size[1]) { assert (ps1->b == -1); assert (ps1->d == -1); } else { assert (ps1->b == 5*(i*NY+j)+1); assert (ps1->d == 5*(i*NY+j)+3); } } } /* * Release resources. */ H5Dclose (dataset); H5Fclose (file); return 0; }