source: src/io/file_hdf5.c @ 6f53da8

feature/crepe
Last change on this file since 6f53da8 was 6f53da8, checked in by Paul Brossier <piem@piem.org>, 2 years ago

[file_hdf5] add list routine

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/*
2  Copyright (C) 2018 Paul Brossier <piem@aubio.org>
3
4  This file is part of aubio.
5
6  aubio is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10
11  aubio is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15
16  You should have received a copy of the GNU General Public License
17  along with aubio.  If not, see <http://www.gnu.org/licenses/>.
18
19*/
20
21#include "aubio_priv.h"
22
23#ifdef HAVE_HDF5
24
25#include "fmat.h"
26#include "ai/tensor.h"
27#include "file_hdf5.h"
28
29#include <hdf5.h>
30#include <hdf5_hl.h>
31
32#if !HAVE_AUBIO_DOUBLE
33#define aubio_H5LTread_dataset_smpl H5LTread_dataset_float
34#else
35#define aubio_H5LTread_dataset_smpl H5LTread_dataset_double
36#endif
37
38#define MAX_DEPTH 100
39
40struct _aubio_file_hdf5_t {
41  const char_t *path;
42  hid_t fid;
43  hid_t datatype;
44};
45
46aubio_file_hdf5_t *new_aubio_file_hdf5(const char_t *path)
47{
48  aubio_file_hdf5_t *f = AUBIO_NEW(aubio_file_hdf5_t);
49
50  f->fid = H5Fopen(path, H5F_ACC_RDONLY, H5P_DEFAULT);
51  if (f->fid <= 0) goto failure;
52
53  // TODO keep a copy
54  f->path = path;
55
56  //AUBIO_DBG("file_hdf5: opened %s\n", f->path);
57  //aubio_file_hdf5_list(f);
58
59  return f;
60
61failure:
62  del_aubio_file_hdf5(f);
63  return NULL;
64}
65
66uint_t aubio_file_hdf5_load_dataset_into_tensor (aubio_file_hdf5_t *f,
67    const char_t *key, aubio_tensor_t *tensor)
68{
69  uint_t i;
70  AUBIO_ASSERT(f && key && tensor);
71  // check arguments
72  if (!f->fid || !key || !tensor)
73    return AUBIO_FAIL;
74  // find key in file
75  hid_t data_id = H5Dopen(f->fid, key, H5P_DEFAULT);
76  if (data_id <= 0) {
77    AUBIO_ERR("file_hdf5: failed getting key %s in %s\n", key, f->path);
78    return AUBIO_FAIL;
79  }
80  // get dimensions
81  hsize_t shape[10];
82  hid_t space = H5Dget_space(data_id);
83  int ndim = H5Sget_simple_extent_dims(space, shape, NULL);
84  if (ndim <= 0) {
85    AUBIO_ERR("file_hdf5: failed to get dims of %s in %s\n", key, f->path);
86    return AUBIO_FAIL;
87  }
88
89  // check output tensor dimension matches
90  AUBIO_ASSERT(ndim == (sint_t)tensor->ndim);
91  for (i = 0; i < (uint_t)ndim; i++) {
92    AUBIO_ASSERT(shape[i] == tensor->shape[i]);
93  }
94
95  if (ndim != (sint_t)tensor->ndim) return AUBIO_FAIL;
96  for (i = 0; i < (uint_t)ndim; i++) {
97    if (shape[i] != tensor->shape[i]) return AUBIO_FAIL;
98  }
99
100  // read data from hdf5 file into tensor buffer
101  smpl_t *buffer = tensor->buffer;
102  herr_t err = aubio_H5LTread_dataset_smpl(f->fid, key, buffer);
103
104  if (err < 0) {
105    return AUBIO_FAIL;
106  }
107
108  //AUBIO_DBG("file_hdf5: loaded : shape %s from key %s\n",
109  //    aubio_tensor_get_shape_string(tensor), key);
110
111  H5Dclose(data_id);
112  return AUBIO_OK;
113}
114
115uint_t aubio_file_hdf5_load_dataset_into_matrix(aubio_file_hdf5_t *f,
116    const char_t *key, fmat_t *mat) {
117  aubio_tensor_t t;
118  if (aubio_fmat_as_tensor (mat, &t)) return AUBIO_FAIL;
119  return aubio_file_hdf5_load_dataset_into_tensor(f, key, &t);
120}
121
122
123uint_t aubio_file_hdf5_load_dataset_into_vector(aubio_file_hdf5_t *f,
124    const char_t *key, fvec_t *vec) {
125  aubio_tensor_t t;
126  if (aubio_fvec_as_tensor (vec, &t)) return AUBIO_FAIL;
127  return aubio_file_hdf5_load_dataset_into_tensor(f, key, &t);
128}
129
130static herr_t aubio_file_hdf5_iterate(hid_t loc_id, const char *name,
131    const H5L_info_t *info UNUSED, void *opdata)
132{
133  H5O_info_t infobuf;
134  const char_t *type_name;
135  uint_t *depth = (uint_t *)opdata;
136  herr_t err = H5Oget_info_by_name(loc_id, name, &infobuf, H5P_DEFAULT);
137  if (err < 0) goto failure;
138  if (*depth > MAX_DEPTH) goto failure;
139  switch (infobuf.type) {
140    case H5O_TYPE_GROUP:
141      type_name = "group";
142      break;
143    case H5O_TYPE_DATASET:
144      type_name = "dataset";
145      break;
146    case H5O_TYPE_NAMED_DATATYPE:
147      type_name = "datatype";
148      break;
149    default:
150      type_name = "unknown";
151      break;
152  }
153  AUBIO_MSG("%*s %s (%s)\n", *depth, "-", name, type_name);
154  if (infobuf.type == H5O_TYPE_GROUP) {
155    uint_t d = *depth + 1;
156    err = H5Literate_by_name(loc_id, name, H5_INDEX_NAME, H5_ITER_NATIVE,
157        NULL, aubio_file_hdf5_iterate, &d, H5P_DEFAULT);
158  }
159failure:
160  return err;
161}
162
163void aubio_file_hdf5_list(aubio_file_hdf5_t *f)
164{
165  uint_t depth = 1;
166  herr_t err = H5Literate(f->fid, H5_INDEX_NAME, H5_ITER_NATIVE,
167      NULL, aubio_file_hdf5_iterate, &depth);
168  if (err < 0)
169    AUBIO_ERR("file_hdf5: failed iterating into %s\n", f->path);
170}
171
172void del_aubio_file_hdf5(aubio_file_hdf5_t *f)
173{
174  AUBIO_ASSERT(f);
175  if (f->fid > 0)
176    H5Fclose(f->fid);
177  AUBIO_FREE(f);
178}
179
180#endif /* HAVE_HDF5 */
Note: See TracBrowser for help on using the repository browser.