5
5
6
6
namespace caffe {
7
7
8
+ // Verifies format of data stored in HDF5 file and reshapes blob accordingly.
9
+ template <typename Dtype>
10
+ void HDF5PrepareBlob (hid_t file_id, const char * dataset_name, int num,
11
+ Blob<Dtype>* blob) {
12
+ // Verify that the dataset exists.
13
+ CHECK (H5LTfind_dataset (file_id, dataset_name))
14
+ << " Failed to find HDF5 dataset " << dataset_name;
15
+ herr_t status;
16
+ int ndims;
17
+ CHECK_LE (0 , H5LTget_dataset_ndims (file_id, dataset_name, &ndims))
18
+ << " Failed to get dataset ndims for " << dataset_name;
19
+ CHECK_GE (ndims, 1 ) << " HDF5 dataset must have at least 1 dimension." ;
20
+ CHECK_LE (ndims, kMaxBlobAxes )
21
+ << " HDF5 dataset must have at most "
22
+ << kMaxBlobAxes << " dimensions, to fit in a Blob." ;
23
+
24
+ // Verify that the data format is what we expect: float or double.
25
+ std::vector<hsize_t > dims (ndims);
26
+ H5T_class_t h5_class;
27
+ status = H5LTget_dataset_info (
28
+ file_id, dataset_name, dims.data (), &h5_class, NULL );
29
+ CHECK_GE (status, 0 ) << " Failed to get dataset info for " << dataset_name;
30
+ CHECK_EQ (h5_class, H5T_FLOAT) << " Expected float or double data" ;
31
+ CHECK_GE (num, -1 ) << " num must be -1 (to indicate the number of rows"
32
+ " in the dataset) or non-negative." ;
33
+
34
+ vector<int > blob_dims (dims.size ());
35
+ blob_dims[0 ] = (num == -1 ) ? dims[0 ] : num;
36
+ for (int i = 1 ; i < dims.size (); ++i) {
37
+ blob_dims[i] = dims[i];
38
+ }
39
+ blob->Reshape (blob_dims);
40
+ }
41
+
42
+ template
43
+ void HDF5PrepareBlob<float >(hid_t file_id, const char * dataset_name, int num,
44
+ Blob<float >* blob);
45
+
46
+ template
47
+ void HDF5PrepareBlob<double >(hid_t file_id, const char * dataset_name, int num,
48
+ Blob<double >* blob);
49
+
50
+ template <typename Dtype>
51
+ int HDF5ReadRowsToBlob (hid_t file_id, const char * dataset_name,
52
+ int h5_offset, int blob_offset, Blob<Dtype>* blob) {
53
+ int ndims;
54
+ CHECK_LE (0 , H5LTget_dataset_ndims (file_id, dataset_name, &ndims))
55
+ << " Failed to get dataset ndims for " << dataset_name;
56
+ std::vector<hsize_t > dims (ndims);
57
+ H5T_class_t h5_class;
58
+ herr_t status = H5LTget_dataset_info (
59
+ file_id, dataset_name, dims.data (), &h5_class, NULL );
60
+ CHECK_GE (status, 0 ) << " Failed to get dataset info for " << dataset_name;
61
+ CHECK_EQ (h5_class, H5T_FLOAT) << " Expected float or double data" ;
62
+ hid_t dataset = H5Dopen2 (file_id, dataset_name, H5P_DEFAULT);
63
+ hid_t dataspace = H5Dget_space (dataset);
64
+ vector<hsize_t > slab_start (ndims, 0 );
65
+ slab_start[0 ] = h5_offset;
66
+ const int num_rows_available = dims[0 ] - h5_offset;
67
+ const int num_rows = std::min (blob->num () - blob_offset, num_rows_available);
68
+ if (num_rows <= 0 ) {
69
+ return 0 ;
70
+ }
71
+ vector<hsize_t > slab_count (ndims, num_rows);
72
+ for (int i = 1 ; i < ndims; ++i) {
73
+ slab_count[i] = dims[i];
74
+ }
75
+ status = H5Sselect_hyperslab (dataspace, H5S_SELECT_SET,
76
+ slab_start.data (), NULL , slab_count.data (), NULL );
77
+ CHECK_GE (status, 0 ) << " Failed to select slab." ;
78
+ hid_t memspace = H5Screate_simple (ndims, slab_count.data (), NULL );
79
+ const int data_size = blob->count () / blob->num ();
80
+ // separate multiplication to avoid a possible overflow
81
+ const int blob_offset_size = blob_offset * data_size;
82
+ hid_t type = (sizeof (Dtype) == 4 ) ? H5T_NATIVE_FLOAT : H5T_NATIVE_DOUBLE;
83
+ status = H5Dread (dataset, type, memspace, dataspace, H5P_DEFAULT,
84
+ blob->mutable_cpu_data () + blob_offset_size);
85
+ CHECK_GE (status, 0 ) << " Failed to read dataset " << dataset_name;
86
+ H5Dclose (dataset);
87
+ H5Sclose (dataspace);
88
+ H5Sclose (memspace);
89
+ return num_rows;
90
+ }
91
+
92
+ template
93
+ int HDF5ReadRowsToBlob<float >(hid_t file_id, const char * dataset_name,
94
+ int h5_offset, int blob_offset, Blob<float >* data);
95
+
96
+ template
97
+ int HDF5ReadRowsToBlob<double >(hid_t file_id, const char * dataset_name,
98
+ int h5_offset, int blob_offset, Blob<double >* data);
99
+
8
100
// Verifies format of data stored in HDF5 file and reshapes blob accordingly.
9
101
template <typename Dtype>
10
102
void hdf5_load_nd_dataset_helper (
@@ -59,7 +151,7 @@ void hdf5_save_nd_dataset<float>(
59
151
const hid_t file_id, const string& dataset_name, const Blob<float >& blob,
60
152
bool write_diff) {
61
153
int num_axes = blob.num_axes ();
62
- hsize_t * dims = new hsize_t [ num_axes] ;
154
+ std::vector< hsize_t > dims ( num_axes) ;
63
155
for (int i = 0 ; i < num_axes; ++i) {
64
156
dims[i] = blob.shape (i);
65
157
}
@@ -70,17 +162,16 @@ void hdf5_save_nd_dataset<float>(
70
162
data = blob.cpu_data ();
71
163
}
72
164
herr_t status = H5LTmake_dataset_float (
73
- file_id, dataset_name.c_str (), num_axes, dims, data);
165
+ file_id, dataset_name.c_str (), num_axes, dims. data () , data);
74
166
CHECK_GE (status, 0 ) << " Failed to make float dataset " << dataset_name;
75
- delete[] dims;
76
167
}
77
168
78
169
template <>
79
170
void hdf5_save_nd_dataset<double >(
80
171
hid_t file_id, const string& dataset_name, const Blob<double >& blob,
81
172
bool write_diff) {
82
173
int num_axes = blob.num_axes ();
83
- hsize_t * dims = new hsize_t [ num_axes] ;
174
+ std::vector< hsize_t > dims ( num_axes) ;
84
175
for (int i = 0 ; i < num_axes; ++i) {
85
176
dims[i] = blob.shape (i);
86
177
}
@@ -91,9 +182,8 @@ void hdf5_save_nd_dataset<double>(
91
182
data = blob.cpu_data ();
92
183
}
93
184
herr_t status = H5LTmake_dataset_double (
94
- file_id, dataset_name.c_str (), num_axes, dims, data);
185
+ file_id, dataset_name.c_str (), num_axes, dims. data () , data);
95
186
CHECK_GE (status, 0 ) << " Failed to make double dataset " << dataset_name;
96
- delete[] dims;
97
187
}
98
188
99
189
string hdf5_load_string (hid_t loc_id, const string& dataset_name) {
0 commit comments