SHOGUN  v3.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HDF5File.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2010 Soeren Sonnenburg
8  * Copyright (C) 2010 Berlin Institute of Technology
9  */
10 
11 #include <shogun/lib/config.h>
12 
13 #ifdef HAVE_HDF5
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <hdf5.h>
18 
19 #include <shogun/lib/memory.h>
20 #include <shogun/io/HDF5File.h>
21 
24 
25 using namespace shogun;
26 
27 CHDF5File::CHDF5File()
28 {
29  SG_UNSTABLE("CHDF5File::CHDF5File()", "\n")
30 
31  get_boolean_type();
32  h5file = -1;
33 }
34 
35 CHDF5File::CHDF5File(char* fname, char rw, const char* name) : CFile()
36 {
37  get_boolean_type();
38  H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
39 
40  if (name)
41  set_variable_name(name);
42 
43  switch (rw)
44  {
45  case 'r':
46  h5file = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
47  break;
48  case 'w':
49  h5file = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
50  break;
51  case 'a':
52  h5file = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT);
53  if (h5file <0)
54  h5file = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
55  break;
56  default:
57  SG_ERROR("unknown mode '%c'\n", rw)
58  };
59 
60  if (h5file<0)
61  SG_ERROR("Could not open file '%s'\n", fname)
62 }
63 
64 CHDF5File::~CHDF5File()
65 {
66  H5Fclose(h5file);
67 }
68 
69 #define GET_VECTOR(fname, sg_type, datatype) \
70 void CHDF5File::fname(sg_type*& vec, int32_t& len) \
71 { \
72  if (!h5file) \
73  SG_ERROR("File invalid.\n") \
74  \
75  int32_t* dims; \
76  int32_t ndims; \
77  int64_t nelements; \
78  hid_t dataset = H5Dopen2(h5file, variable_name, H5P_DEFAULT); \
79  if (dataset<0) \
80  SG_ERROR("Error opening data set\n") \
81  hid_t dtype = H5Dget_type(dataset); \
82  H5T_class_t t_class=H5Tget_class(dtype); \
83  TSGDataType t datatype; hid_t h5_type=get_compatible_type(t_class, &t); \
84  if (h5_type==-1) \
85  { \
86  H5Dclose(dataset); \
87  SG_INFO("No compatible datatype found\n") \
88  } \
89  get_dims(dataset, dims, ndims, nelements); \
90  if (!((ndims==2 && dims[0]==nelements && dims[1]==1) || \
91  (ndims==2 && dims[0]==1 && dims[1]==nelements) || \
92  (ndims==1 && dims[0]==nelements))) \
93  SG_ERROR("Error not a 1-dimensional vector (ndims=%d, dims[0]=%d)\n", ndims, dims[0]) \
94  vec=SG_MALLOC(sg_type, nelements); \
95  len=nelements; \
96  herr_t status = H5Dread(dataset, h5_type, H5S_ALL, \
97  H5S_ALL, H5P_DEFAULT, vec); \
98  H5Dclose(dataset); \
99  H5Tclose(dtype); \
100  SG_FREE(dims); \
101  if (status<0) \
102  { \
103  SG_FREE(vec); \
104  SG_ERROR("Error reading dataset\n") \
105  } \
106 }
107 
108 GET_VECTOR(get_vector, bool, (CT_VECTOR, ST_NONE, PT_BOOL))
109 GET_VECTOR(get_vector, int8_t, (CT_VECTOR, ST_NONE, PT_INT8))
110 GET_VECTOR(get_vector, uint8_t, (CT_VECTOR, ST_NONE, PT_UINT8))
111 GET_VECTOR(get_vector, char, (CT_VECTOR, ST_NONE, PT_CHAR))
112 GET_VECTOR(get_vector, int32_t, (CT_VECTOR, ST_NONE, PT_INT32))
113 GET_VECTOR(get_vector, uint32_t, (CT_VECTOR, ST_NONE, PT_UINT32))
114 GET_VECTOR(get_vector, float32_t, (CT_VECTOR, ST_NONE, PT_FLOAT32))
115 GET_VECTOR(get_vector, float64_t, (CT_VECTOR, ST_NONE, PT_FLOAT64))
116 GET_VECTOR(get_vector, floatmax_t, (CT_VECTOR, ST_NONE, PT_FLOATMAX))
117 GET_VECTOR(get_vector, int16_t, (CT_VECTOR, ST_NONE, PT_INT16))
118 GET_VECTOR(get_vector, uint16_t, (CT_VECTOR, ST_NONE, PT_INT16))
119 GET_VECTOR(get_vector, int64_t, (CT_VECTOR, ST_NONE, PT_INT64))
120 GET_VECTOR(get_vector, uint64_t, (CT_VECTOR, ST_NONE, PT_UINT64))
121 #undef GET_VECTOR
122 
123 #define GET_MATRIX(fname, sg_type, datatype) \
124 void CHDF5File::fname(sg_type*& matrix, int32_t& num_feat, int32_t& num_vec) \
125 { \
126  if (!h5file) \
127  SG_ERROR("File invalid.\n") \
128  \
129  int32_t* dims; \
130  int32_t ndims; \
131  int64_t nelements; \
132  hid_t dataset = H5Dopen2(h5file, variable_name, H5P_DEFAULT); \
133  if (dataset<0) \
134  SG_ERROR("Error opening data set\n") \
135  hid_t dtype = H5Dget_type(dataset); \
136  H5T_class_t t_class=H5Tget_class(dtype); \
137  TSGDataType t datatype; hid_t h5_type=get_compatible_type(t_class, &t); \
138  if (h5_type==-1) \
139  { \
140  H5Dclose(dataset); \
141  SG_INFO("No compatible datatype found\n") \
142  } \
143  get_dims(dataset, dims, ndims, nelements); \
144  if (ndims!=2) \
145  SG_ERROR("Error not a 2-dimensional matrix\n") \
146  matrix=SG_MALLOC(sg_type, nelements); \
147  num_feat=dims[0]; \
148  num_vec=dims[1]; \
149  herr_t status = H5Dread(dataset, h5_type, H5S_ALL, \
150  H5S_ALL, H5P_DEFAULT, matrix); \
151  H5Dclose(dataset); \
152  H5Tclose(dtype); \
153  SG_FREE(dims); \
154  if (status<0) \
155  { \
156  SG_FREE(matrix); \
157  SG_ERROR("Error reading dataset\n") \
158  } \
159 }
160 
161 GET_MATRIX(get_matrix, bool, (CT_MATRIX, ST_NONE, PT_BOOL))
162 GET_MATRIX(get_matrix, char, (CT_MATRIX, ST_NONE, PT_CHAR))
163 GET_MATRIX(get_matrix, uint8_t, (CT_MATRIX, ST_NONE, PT_UINT8))
164 GET_MATRIX(get_matrix, int32_t, (CT_MATRIX, ST_NONE, PT_INT32))
165 GET_MATRIX(get_matrix, uint32_t, (CT_MATRIX, ST_NONE, PT_INT32))
166 GET_MATRIX(get_matrix, int64_t, (CT_MATRIX, ST_NONE, PT_INT64))
167 GET_MATRIX(get_matrix, uint64_t, (CT_MATRIX, ST_NONE, PT_INT64))
168 GET_MATRIX(get_matrix, int16_t, (CT_MATRIX, ST_NONE, PT_INT16))
169 GET_MATRIX(get_matrix, uint16_t, (CT_MATRIX, ST_NONE, PT_INT16))
170 GET_MATRIX(get_matrix, float32_t, (CT_MATRIX, ST_NONE, PT_FLOAT32))
171 GET_MATRIX(get_matrix, float64_t, (CT_MATRIX, ST_NONE, PT_FLOAT64))
172 GET_MATRIX(get_matrix, floatmax_t, (CT_MATRIX, ST_NONE, PT_FLOATMAX))
173 #undef GET_MATRIX
174 
175 void CHDF5File::get_ndarray(uint8_t*& array, int32_t*& dims, int32_t& num_dims)
176 {
177 }
178 
179 void CHDF5File::get_ndarray(char*& array, int32_t*& dims, int32_t& num_dims)
180 {
181 }
182 
183 void CHDF5File::get_ndarray(int32_t*& array, int32_t*& dims, int32_t& num_dims)
184 {
185 }
186 
187 void CHDF5File::get_ndarray(float32_t*& array, int32_t*& dims, int32_t& num_dims)
188 {
189 }
190 
191 void CHDF5File::get_ndarray(float64_t*& array, int32_t*& dims, int32_t& num_dims)
192 {
193 }
194 
195 void CHDF5File::get_ndarray(int16_t*& array, int32_t*& dims, int32_t& num_dims)
196 {
197 }
198 
199 void CHDF5File::get_ndarray(uint16_t*& array, int32_t*& dims, int32_t& num_dims)
200 {
201 }
202 
203 #define GET_SPARSEMATRIX(fname, sg_type, datatype) \
204 void CHDF5File::fname(SGSparseVector<sg_type>*& matrix, int32_t& num_feat, int32_t& num_vec) \
205 { \
206  if (!(file)) \
207  SG_ERROR("File invalid.\n") \
208 }
209 GET_SPARSEMATRIX(get_sparse_matrix, bool, DT_SPARSE_BOOL)
210 GET_SPARSEMATRIX(get_sparse_matrix, char, DT_SPARSE_CHAR)
211 GET_SPARSEMATRIX(get_sparse_matrix, int8_t, DT_SPARSE_INT8)
212 GET_SPARSEMATRIX(get_sparse_matrix, uint8_t, DT_SPARSE_BYTE)
213 GET_SPARSEMATRIX(get_sparse_matrix, int32_t, DT_SPARSE_INT)
214 GET_SPARSEMATRIX(get_sparse_matrix, uint32_t, DT_SPARSE_UINT)
215 GET_SPARSEMATRIX(get_sparse_matrix, int64_t, DT_SPARSE_LONG)
216 GET_SPARSEMATRIX(get_sparse_matrix, uint64_t, DT_SPARSE_ULONG)
217 GET_SPARSEMATRIX(get_sparse_matrix, int16_t, DT_SPARSE_SHORT)
218 GET_SPARSEMATRIX(get_sparse_matrix, uint16_t, DT_SPARSE_WORD)
219 GET_SPARSEMATRIX(get_sparse_matrix, float32_t, DT_SPARSE_SHORTREAL)
220 GET_SPARSEMATRIX(get_sparse_matrix, float64_t, DT_SPARSE_REAL)
221 GET_SPARSEMATRIX(get_sparse_matrix, floatmax_t, DT_SPARSE_LONGREAL)
222 #undef GET_SPARSEMATRIX
223 
224 
225 #define GET_STRING_LIST(fname, sg_type, datatype) \
226 void CHDF5File::fname(SGString<sg_type>*& strings, int32_t& num_str, int32_t& max_string_len) \
227 { \
228 }
229 
230 GET_STRING_LIST(get_string_list, bool, DT_STRING_BOOL)
231 GET_STRING_LIST(get_string_list, char, DT_STRING_CHAR)
232 GET_STRING_LIST(get_string_list, int8_t, DT_STRING_INT8)
233 GET_STRING_LIST(get_string_list, uint8_t, DT_STRING_BYTE)
234 GET_STRING_LIST(get_string_list, int32_t, DT_STRING_INT)
235 GET_STRING_LIST(get_string_list, uint32_t, DT_STRING_UINT)
236 GET_STRING_LIST(get_string_list, int64_t, DT_STRING_LONG)
237 GET_STRING_LIST(get_string_list, uint64_t, DT_STRING_ULONG)
238 GET_STRING_LIST(get_string_list, int16_t, DT_STRING_SHORT)
239 GET_STRING_LIST(get_string_list, uint16_t, DT_STRING_WORD)
240 GET_STRING_LIST(get_string_list, float32_t, DT_STRING_SHORTREAL)
241 GET_STRING_LIST(get_string_list, float64_t, DT_STRING_REAL)
242 GET_STRING_LIST(get_string_list, floatmax_t, DT_STRING_LONGREAL)
243 #undef GET_STRING_LIST
244 
247 #define SET_VECTOR(fname, sg_type, dtype, h5type) \
248 void CHDF5File::fname(const sg_type* vec, int32_t len) \
249 { \
250  if (h5file<0 || !vec) \
251  SG_ERROR("File or vector invalid.\n") \
252  \
253  create_group_hierarchy(); \
254  \
255  hsize_t dims=(hsize_t) len; \
256  hid_t dataspace, dataset, status; \
257  dataspace=H5Screate_simple(1, &dims, NULL); \
258  if (dataspace<0) \
259  SG_ERROR("Could not create hdf5 dataspace\n") \
260  dataset=H5Dcreate2(h5file, variable_name, h5type, dataspace, H5P_DEFAULT,\
261  H5P_DEFAULT, H5P_DEFAULT); \
262  if (dataset<0) \
263  { \
264  SG_ERROR("Could not create hdf5 dataset - does" \
265  " dataset '%s' already exist?\n", variable_name); \
266  } \
267  status=H5Dwrite(dataset, h5type, H5S_ALL, H5S_ALL, H5P_DEFAULT, vec); \
268  if (status<0) \
269  SG_ERROR("Failed to write hdf5 dataset\n") \
270  H5Dclose(dataset); \
271  H5Sclose(dataspace); \
272 }
273 SET_VECTOR(set_vector, bool, DT_VECTOR_BOOL, boolean_type)
274 SET_VECTOR(set_vector, int8_t, DT_VECTOR_BYTE, H5T_NATIVE_INT8)
275 SET_VECTOR(set_vector, uint8_t, DT_VECTOR_BYTE, H5T_NATIVE_UINT8)
276 SET_VECTOR(set_vector, char, DT_VECTOR_CHAR, H5T_NATIVE_CHAR)
277 SET_VECTOR(set_vector, int32_t, DT_VECTOR_INT, H5T_NATIVE_INT32)
278 SET_VECTOR(set_vector, uint32_t, DT_VECTOR_UINT, H5T_NATIVE_UINT32)
279 SET_VECTOR(set_vector, float32_t, DT_VECTOR_SHORTREAL, H5T_NATIVE_FLOAT)
280 SET_VECTOR(set_vector, float64_t, DT_VECTOR_REAL, H5T_NATIVE_DOUBLE)
281 SET_VECTOR(set_vector, floatmax_t, DT_VECTOR_LONGREAL, H5T_NATIVE_LDOUBLE)
282 SET_VECTOR(set_vector, int16_t, DT_VECTOR_SHORT, H5T_NATIVE_INT16)
283 SET_VECTOR(set_vector, uint16_t, DT_VECTOR_WORD, H5T_NATIVE_UINT16)
284 SET_VECTOR(set_vector, int64_t, DT_VECTOR_LONG, H5T_NATIVE_LLONG)
285 SET_VECTOR(set_vector, uint64_t, DT_VECTOR_ULONG, H5T_NATIVE_ULLONG)
286 #undef SET_VECTOR
287 
288 #define SET_MATRIX(fname, sg_type, dtype, h5type) \
289 void CHDF5File::fname(const sg_type* matrix, int32_t num_feat, int32_t num_vec) \
290 { \
291  if (h5file<0 || !matrix) \
292  SG_ERROR("File or matrix invalid.\n") \
293  \
294  create_group_hierarchy(); \
295  \
296  hsize_t dims[2]={(hsize_t) num_feat, (hsize_t) num_vec}; \
297  hid_t dataspace, dataset, status; \
298  dataspace=H5Screate_simple(2, dims, NULL); \
299  if (dataspace<0) \
300  SG_ERROR("Could not create hdf5 dataspace\n") \
301  dataset=H5Dcreate2(h5file, variable_name, h5type, dataspace, H5P_DEFAULT, \
302  H5P_DEFAULT, H5P_DEFAULT); \
303  if (dataset<0) \
304  { \
305  SG_ERROR("Could not create hdf5 dataset - does" \
306  " dataset '%s' already exist?\n", variable_name); \
307  } \
308  status=H5Dwrite(dataset, h5type, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix); \
309  if (status<0) \
310  SG_ERROR("Failed to write hdf5 dataset\n") \
311  H5Dclose(dataset); \
312  H5Sclose(dataspace); \
313 }
314 SET_MATRIX(set_matrix, bool, DT_DENSE_BOOL, boolean_type)
315 SET_MATRIX(set_matrix, char, DT_DENSE_CHAR, H5T_NATIVE_CHAR)
316 SET_MATRIX(set_matrix, int8_t, DT_DENSE_BYTE, H5T_NATIVE_INT8)
317 SET_MATRIX(set_matrix, uint8_t, DT_DENSE_BYTE, H5T_NATIVE_UINT8)
318 SET_MATRIX(set_matrix, int32_t, DT_DENSE_INT, H5T_NATIVE_INT32)
319 SET_MATRIX(set_matrix, uint32_t, DT_DENSE_UINT, H5T_NATIVE_UINT32)
320 SET_MATRIX(set_matrix, int64_t, DT_DENSE_LONG, H5T_NATIVE_INT64)
321 SET_MATRIX(set_matrix, uint64_t, DT_DENSE_ULONG, H5T_NATIVE_UINT64)
322 SET_MATRIX(set_matrix, int16_t, DT_DENSE_SHORT, H5T_NATIVE_INT16)
323 SET_MATRIX(set_matrix, uint16_t, DT_DENSE_WORD, H5T_NATIVE_UINT16)
324 SET_MATRIX(set_matrix, float32_t, DT_DENSE_SHORTREAL, H5T_NATIVE_FLOAT)
325 SET_MATRIX(set_matrix, float64_t, DT_DENSE_REAL, H5T_NATIVE_DOUBLE)
326 SET_MATRIX(set_matrix, floatmax_t, DT_DENSE_LONGREAL, H5T_NATIVE_LDOUBLE)
327 #undef SET_MATRIX
328 
329 #define SET_SPARSEMATRIX(fname, sg_type, dtype) \
330 void CHDF5File::fname(const SGSparseVector<sg_type>* matrix, \
331  int32_t num_feat, int32_t num_vec) \
332 { \
333  if (!(file && matrix)) \
334  SG_ERROR("File or matrix invalid.\n") \
335  \
336 }
337 SET_SPARSEMATRIX(set_sparse_matrix, bool, DT_SPARSE_BOOL)
338 SET_SPARSEMATRIX(set_sparse_matrix, char, DT_SPARSE_CHAR)
339 SET_SPARSEMATRIX(set_sparse_matrix, int8_t, DT_SPARSE_INT8)
340 SET_SPARSEMATRIX(set_sparse_matrix, uint8_t, DT_SPARSE_BYTE)
341 SET_SPARSEMATRIX(set_sparse_matrix, int32_t, DT_SPARSE_INT)
342 SET_SPARSEMATRIX(set_sparse_matrix, uint32_t, DT_SPARSE_UINT)
343 SET_SPARSEMATRIX(set_sparse_matrix, int64_t, DT_SPARSE_LONG)
344 SET_SPARSEMATRIX(set_sparse_matrix, uint64_t, DT_SPARSE_ULONG)
345 SET_SPARSEMATRIX(set_sparse_matrix, int16_t, DT_SPARSE_SHORT)
346 SET_SPARSEMATRIX(set_sparse_matrix, uint16_t, DT_SPARSE_WORD)
347 SET_SPARSEMATRIX(set_sparse_matrix, float32_t, DT_SPARSE_SHORTREAL)
348 SET_SPARSEMATRIX(set_sparse_matrix, float64_t, DT_SPARSE_REAL)
349 SET_SPARSEMATRIX(set_sparse_matrix, floatmax_t, DT_SPARSE_LONGREAL)
350 #undef SET_SPARSEMATRIX
351 
352 #define SET_STRING_LIST(fname, sg_type, dtype) \
353 void CHDF5File::fname(const SGString<sg_type>* strings, int32_t num_str) \
354 { \
355  if (!(file && strings)) \
356  SG_ERROR("File or strings invalid.\n") \
357  \
358 }
359 SET_STRING_LIST(set_string_list, bool, DT_STRING_BOOL)
360 SET_STRING_LIST(set_string_list, char, DT_STRING_CHAR)
361 SET_STRING_LIST(set_string_list, int8_t, DT_STRING_INT8)
362 SET_STRING_LIST(set_string_list, uint8_t, DT_STRING_BYTE)
363 SET_STRING_LIST(set_string_list, int32_t, DT_STRING_INT)
364 SET_STRING_LIST(set_string_list, uint32_t, DT_STRING_UINT)
365 SET_STRING_LIST(set_string_list, int64_t, DT_STRING_LONG)
366 SET_STRING_LIST(set_string_list, uint64_t, DT_STRING_ULONG)
367 SET_STRING_LIST(set_string_list, int16_t, DT_STRING_SHORT)
368 SET_STRING_LIST(set_string_list, uint16_t, DT_STRING_WORD)
369 SET_STRING_LIST(set_string_list, float32_t, DT_STRING_SHORTREAL)
370 SET_STRING_LIST(set_string_list, float64_t, DT_STRING_REAL)
371 SET_STRING_LIST(set_string_list, floatmax_t, DT_STRING_LONGREAL)
372 #undef SET_STRING_LIST
373 
374 void CHDF5File::get_boolean_type()
375 {
376  boolean_type=H5T_NATIVE_UCHAR;
377  switch (sizeof(bool))
378  {
379  case 1:
380  boolean_type = H5T_NATIVE_UCHAR;
381  break;
382  case 2:
383  boolean_type = H5T_NATIVE_UINT16;
384  break;
385  case 4:
386  boolean_type = H5T_NATIVE_UINT32;
387  break;
388  case 8:
389  boolean_type = H5T_NATIVE_UINT64;
390  break;
391  default:
392  SG_ERROR("Boolean type not supported on this platform\n")
393  }
394 }
395 
396 hid_t CHDF5File::get_compatible_type(H5T_class_t t_class,
397  const TSGDataType* datatype)
398 {
399  switch (t_class)
400  {
401  case H5T_FLOAT:
402  case H5T_INTEGER:
403  switch (datatype->m_ptype)
404  {
405  case PT_BOOL: return boolean_type;
406  case PT_CHAR: return H5T_NATIVE_CHAR;
407  case PT_INT8: return H5T_NATIVE_INT8;
408  case PT_UINT8: return H5T_NATIVE_UINT8;
409  case PT_INT16: return H5T_NATIVE_INT16;
410  case PT_UINT16: return H5T_NATIVE_UINT16;
411  case PT_INT32: return H5T_NATIVE_INT32;
412  case PT_UINT32: return H5T_NATIVE_UINT32;
413  case PT_INT64: return H5T_NATIVE_INT64;
414  case PT_UINT64: return H5T_NATIVE_UINT64;
415  case PT_FLOAT32: return H5T_NATIVE_FLOAT;
416  case PT_FLOAT64: return H5T_NATIVE_DOUBLE;
417  case PT_FLOATMAX: return H5T_NATIVE_LDOUBLE;
418  case PT_COMPLEX128:
419  SG_ERROR("complex128_t not compatible with HDF5File!");
420  return -1;
421  case PT_SGOBJECT:
422  SG_ERROR("Implementation error during writing "
423  "HDF5File!");
424  return -1;
425  }
426  case H5T_STRING:
427  SG_ERROR("Strings not supported")
428  return -1;
429  case H5T_VLEN:
430  SG_ERROR("Variable length containers currently not supported")
431  return -1;
432  case H5T_ARRAY:
433  SG_ERROR("Array containers currently not supported")
434  return -1;
435  default:
436  SG_ERROR("Datatype mismatchn")
437  return -1;
438  }
439 }
440 
441 void CHDF5File::get_dims(hid_t dataset, int32_t*& dims, int32_t& ndims, int64_t& total_elements)
442 {
443  hid_t dataspace = H5Dget_space(dataset);
444  if (dataspace<0)
445  SG_ERROR("Error obtaining hdf5 dataspace\n")
446 
447  ndims = H5Sget_simple_extent_ndims(dataspace);
448  total_elements=H5Sget_simple_extent_npoints(dataspace);
449  hsize_t* dims_out=SG_MALLOC(hsize_t, ndims);
450  dims=SG_MALLOC(int32_t, ndims);
451  H5Sget_simple_extent_dims(dataspace, dims_out, NULL);
452  for (int32_t i=0; i<ndims; i++)
453  dims[i]=dims_out[i];
454  SG_FREE(dims_out);
455  H5Sclose(dataspace);
456 }
457 
458 void CHDF5File::create_group_hierarchy()
459 {
460  char* vname=get_strdup(variable_name);
461  int32_t vlen=strlen(vname);
462  for (int32_t i=0; i<vlen; i++)
463  {
464  if (i!=0 && vname[i]=='/')
465  {
466  vname[i]='\0';
467  hid_t g = H5Gopen2(h5file, vname, H5P_DEFAULT);
468  if (g<0)
469  {
470  g=H5Gcreate2(h5file, vname, H5P_DEFAULT, H5P_DEFAULT,
471  H5P_DEFAULT);
472  if (g<0)
473  SG_ERROR("Error creating group '%s'\n", vname)
474  vname[i]='/';
475  }
476  H5Gclose(g);
477  }
478  }
479  SG_FREE(vname);
480 }
481 #endif // HDF5

SHOGUN Machine Learning Toolbox - Documentation