aboutsummaryrefslogtreecommitdiff
path: root/doc/CreateIOHDF5datafile.c
blob: 00c9c76e5bbf871d53cfacc7ad87695c34781344 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
 /*@@
   @file      CreateIOHDF5datafile.c
   @date      Mon 12 Mar 2001
   @author    Thomas Radke
   @desc
              Example program to create an unchunked HDF5 datafile
              with a single dataset which can be read as input data
              into Cactus.
   @enddesc
   @version   $Id$
 @@*/


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


/* the name of our sample data file */
#define DATAFILENAME  "x.h5"

/* the number of dimensions of our sample data array and its size */
#define  NDIM         3
#define  NSIZE        20

/* maximum size of the dataset name */
#define  MAXNAMESIZE  100

/* the name of the attributes' group describing how the data file was created
   and what type of Cactus variable the sample dataset is (a grid function)
   These definitions were taken from Cactus header files - for ease of use
   we didn't include these here. */
#define GLOBAL_ATTRIBUTES_GROUP  "Global Attributes"
#define CCTK_GF                  2

/* the Cactus version that this datafile is (upwards) compatible with 
   (versions below beta10 use a different timelevel scheme) */
#define CACTUS_VERSION  "4.0.b10"

/* a simple macro to do an HDF5 call with return code checking
   in case of an error it will issue an error message and exit */
#define CHECK_ERROR(hdf5_call)                                                \
          {                                                                   \
            int _error_code = hdf5_call;                                      \
                                                                              \
                                                                              \
            if (_error_code < 0)                                              \
            {                                                                 \
              fprintf (stderr, "ERROR: line %d: HDF5 call '%s' returned "     \
                               "error code %d\n",                             \
                                __LINE__, #hdf5_call, _error_code);           \
              return (-1);                                                    \
            }                                                                 \
          }


 /*@@
   @routine    main
   @date       Mon 12 Mar 2001
   @author     Thomas Radke
   @desc
               Main routine creating a sample HDF5 datafile
   @enddesc

   @returntype int
   @returndesc
               0 for success, negative return values indicate an error
   @endreturndesc
@@*/
int main (void)
{
  void *data;
  int i, elements;
  int iteration, grouptype;
  int timelevel, ntimelevels;
  int nprocs, ioproc_every, unchunked;
  hsize_t dims[NDIM];
  char datasetname[MAXNAMESIZE], *varname, *groupname;
  hid_t datafile, group, attr, dataset, dataspace, stringtype;


  /* create a datafile (truncate if already exists) */
  datafile = H5Fcreate (DATAFILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
  if (datafile < 0)
  {
    fprintf (stderr, "Could not create output file '%s'\n", DATAFILENAME);
    return (-1);
  }

  /* set the dimensions of our sample data array
     count the number of elements */
  elements = 1;
  for (i = 0; i < NDIM; i++)
  {
    dims[i] = NSIZE;
    elements *= NSIZE;
  }
  /* allocate the data array
     we are lazy here and only initialize it to zero */
  data = calloc (elements, sizeof (double));

  CHECK_ERROR (stringtype = H5Tcopy (H5T_C_S1));


  /**************************************************************************/
  /* create a group with attributes describing how the data in this file    */
  /* was written                                                            */
  /**************************************************************************/

  CHECK_ERROR (dataspace = H5Screate (H5S_SCALAR));
  CHECK_ERROR (group = H5Gcreate (datafile, GLOBAL_ATTRIBUTES_GROUP, 0));

  /* we are writing unchunked data */
  unchunked = 1;
  CHECK_ERROR (attr = H5Acreate (group, "unchunked", H5T_NATIVE_INT,
                                 dataspace, H5P_DEFAULT));
  CHECK_ERROR (H5Awrite (attr, H5T_NATIVE_INT, &unchunked));
  CHECK_ERROR (H5Aclose (attr));

  /* the number of processors isn't really needed here
     (only for chunked data) */
  nprocs = 1;
  CHECK_ERROR (attr = H5Acreate (group, "nprocs", H5T_NATIVE_INT,
                                 dataspace, H5P_DEFAULT));
  CHECK_ERROR (H5Awrite (attr, H5T_NATIVE_INT, &nprocs));
  CHECK_ERROR (H5Aclose (attr));

  /* the number of I/O processors isn't really needed here
     (only for chunked data) */
  ioproc_every = 1;
  CHECK_ERROR (attr = H5Acreate (group, "ioproc_every", H5T_NATIVE_INT,
                                 dataspace, H5P_DEFAULT));
  CHECK_ERROR (H5Awrite (attr, H5T_NATIVE_INT, &ioproc_every));
  CHECK_ERROR (H5Aclose (attr));

  /* the version of Cactus that this datafile is (upwards) compatible with */
  CHECK_ERROR (H5Tset_size (stringtype, strlen (CACTUS_VERSION)));
  CHECK_ERROR (attr = H5Acreate (group, "Cactus version", stringtype,
                                 dataspace, H5P_DEFAULT));
  CHECK_ERROR (H5Awrite (attr, stringtype, CACTUS_VERSION));
  CHECK_ERROR (H5Aclose (attr));

  CHECK_ERROR (H5Gclose (group));
  CHECK_ERROR (H5Sclose (dataspace));


  /**************************************************************************/
  /* write your data as a dataset into the file                             */
  /* the dataset name template has the format                               */
  /*   "<full_varname> timelevel <timelevel> at iteration <iteration>"      */
  /**************************************************************************/

  /* the name of the grid variable (as specified in the interface.ccl file) */
  varname = "grid::x";
  /* the timelevel of the variable (set to 0 if there's just one timelevel) */
  timelevel = 0;
  /* iteration isn't really used here */
  iteration = 0;
  sprintf (datasetname, "%s timelevel %d at iteration %d",
           varname, timelevel, iteration);

  /* dataspace is given by dims[] */
  CHECK_ERROR (dataspace = H5Screate_simple (NDIM, dims, NULL));
  CHECK_ERROR (dataset = H5Dcreate (datafile, datasetname, H5T_NATIVE_DOUBLE,
                                    dataspace, H5P_DEFAULT));

  /* write the data */
  CHECK_ERROR (H5Dwrite (dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
                         H5P_DEFAULT, data));
  CHECK_ERROR (H5Sclose (dataspace));


  /**************************************************************************/
  /* add the necessary attributes describing the dataset                    */
  /* as a Cactus grid variable                                              */
  /**************************************************************************/
  /* the variable's group name (as specified in the interface.ccl file) */
  groupname = "grid::coordinates";
  CHECK_ERROR (dataspace = H5Screate (H5S_SCALAR));
  CHECK_ERROR (H5Tset_size (stringtype, strlen (groupname)));
  CHECK_ERROR (attr = H5Acreate (dataset, "groupname", stringtype,
                                 dataspace, H5P_DEFAULT));
  CHECK_ERROR (H5Awrite (attr, stringtype, groupname));
  CHECK_ERROR (H5Aclose (attr));

  /* the variable's group type (as specified in the interface.ccl file) */
  grouptype = CCTK_GF;
  CHECK_ERROR (attr = H5Acreate (dataset, "grouptype", H5T_NATIVE_INT,
                                 dataspace, H5P_DEFAULT));
  CHECK_ERROR (H5Awrite (attr, H5T_NATIVE_INT, &grouptype));
  CHECK_ERROR (H5Aclose (attr));

  /* the number of timelevels of the variable (as specified in the
     interface.ccl file) */
  ntimelevels = 1;
  CHECK_ERROR (attr = H5Acreate (dataset, "ntimelevels", H5T_NATIVE_INT,
                                 dataspace, H5P_DEFAULT));
  CHECK_ERROR (H5Awrite (attr, H5T_NATIVE_INT, &ntimelevels));
  CHECK_ERROR (H5Aclose (attr));
  CHECK_ERROR (H5Sclose (dataspace));


  /* close remaining HDF5 objects and free allocated resources */
  CHECK_ERROR (H5Dclose (dataset));
  CHECK_ERROR (H5Tclose (stringtype));
  CHECK_ERROR (H5Fclose (datafile));
  free (data);

  return (0);
}