00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef OPENCV_FLANN_HDF5_H_
00031 #define OPENCV_FLANN_HDF5_H_
00032
00033 #include <hdf5.h>
00034
00035 #include "matrix.h"
00036
00037
00038 namespace cvflann
00039 {
00040
00041 namespace
00042 {
00043
00044 template<typename T>
00045 hid_t get_hdf5_type()
00046 {
00047 throw FLANNException("Unsupported type for IO operations");
00048 }
00049
00050 template<>
00051 hid_t get_hdf5_type<char>() { return H5T_NATIVE_CHAR; }
00052 template<>
00053 hid_t get_hdf5_type<unsigned char>() { return H5T_NATIVE_UCHAR; }
00054 template<>
00055 hid_t get_hdf5_type<short int>() { return H5T_NATIVE_SHORT; }
00056 template<>
00057 hid_t get_hdf5_type<unsigned short int>() { return H5T_NATIVE_USHORT; }
00058 template<>
00059 hid_t get_hdf5_type<int>() { return H5T_NATIVE_INT; }
00060 template<>
00061 hid_t get_hdf5_type<unsigned int>() { return H5T_NATIVE_UINT; }
00062 template<>
00063 hid_t get_hdf5_type<long>() { return H5T_NATIVE_LONG; }
00064 template<>
00065 hid_t get_hdf5_type<unsigned long>() { return H5T_NATIVE_ULONG; }
00066 template<>
00067 hid_t get_hdf5_type<float>() { return H5T_NATIVE_FLOAT; }
00068 template<>
00069 hid_t get_hdf5_type<double>() { return H5T_NATIVE_DOUBLE; }
00070 }
00071
00072
00073 #define CHECK_ERROR(x,y) if ((x)<0) throw FLANNException((y));
00074
00075 template<typename T>
00076 void save_to_file(const cvflann::Matrix<T>& dataset, const std::string& filename, const std::string& name)
00077 {
00078
00079 #if H5Eset_auto_vers == 2
00080 H5Eset_auto( H5E_DEFAULT, NULL, NULL );
00081 #else
00082 H5Eset_auto( NULL, NULL );
00083 #endif
00084
00085 herr_t status;
00086 hid_t file_id;
00087 file_id = H5Fopen(filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
00088 if (file_id < 0) {
00089 file_id = H5Fcreate(filename.c_str(), H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT);
00090 }
00091 CHECK_ERROR(file_id,"Error creating hdf5 file.");
00092
00093 hsize_t dimsf[2];
00094 dimsf[0] = dataset.rows;
00095 dimsf[1] = dataset.cols;
00096
00097 hid_t space_id = H5Screate_simple(2, dimsf, NULL);
00098 hid_t memspace_id = H5Screate_simple(2, dimsf, NULL);
00099
00100 hid_t dataset_id;
00101 #if H5Dcreate_vers == 2
00102 dataset_id = H5Dcreate2(file_id, name.c_str(), get_hdf5_type<T>(), space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00103 #else
00104 dataset_id = H5Dcreate(file_id, name.c_str(), get_hdf5_type<T>(), space_id, H5P_DEFAULT);
00105 #endif
00106
00107 if (dataset_id<0) {
00108 #if H5Dopen_vers == 2
00109 dataset_id = H5Dopen2(file_id, name.c_str(), H5P_DEFAULT);
00110 #else
00111 dataset_id = H5Dopen(file_id, name.c_str());
00112 #endif
00113 }
00114 CHECK_ERROR(dataset_id,"Error creating or opening dataset in file.");
00115
00116 status = H5Dwrite(dataset_id, get_hdf5_type<T>(), memspace_id, space_id, H5P_DEFAULT, dataset.data );
00117 CHECK_ERROR(status, "Error writing to dataset");
00118
00119 H5Sclose(memspace_id);
00120 H5Sclose(space_id);
00121 H5Dclose(dataset_id);
00122 H5Fclose(file_id);
00123
00124 }
00125
00126
00127 template<typename T>
00128 void load_from_file(cvflann::Matrix<T>& dataset, const std::string& filename, const std::string& name)
00129 {
00130 herr_t status;
00131 hid_t file_id = H5Fopen(filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
00132 CHECK_ERROR(file_id,"Error opening hdf5 file.");
00133
00134 hid_t dataset_id;
00135 #if H5Dopen_vers == 2
00136 dataset_id = H5Dopen2(file_id, name.c_str(), H5P_DEFAULT);
00137 #else
00138 dataset_id = H5Dopen(file_id, name.c_str());
00139 #endif
00140 CHECK_ERROR(dataset_id,"Error opening dataset in file.");
00141
00142 hid_t space_id = H5Dget_space(dataset_id);
00143
00144 hsize_t dims_out[2];
00145 H5Sget_simple_extent_dims(space_id, dims_out, NULL);
00146
00147 dataset = cvflann::Matrix<T>(new T[dims_out[0]*dims_out[1]], dims_out[0], dims_out[1]);
00148
00149 status = H5Dread(dataset_id, get_hdf5_type<T>(), H5S_ALL, H5S_ALL, H5P_DEFAULT, dataset[0]);
00150 CHECK_ERROR(status, "Error reading dataset");
00151
00152 H5Sclose(space_id);
00153 H5Dclose(dataset_id);
00154 H5Fclose(file_id);
00155 }
00156
00157
00158 #ifdef HAVE_MPI
00159
00160 namespace mpi
00161 {
00168 template<typename T>
00169 void load_from_file(cvflann::Matrix<T>& dataset, const std::string& filename, const std::string& name)
00170 {
00171 MPI_Comm comm = MPI_COMM_WORLD;
00172 MPI_Info info = MPI_INFO_NULL;
00173
00174 int mpi_size, mpi_rank;
00175 MPI_Comm_size(comm, &mpi_size);
00176 MPI_Comm_rank(comm, &mpi_rank);
00177
00178 herr_t status;
00179
00180 hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS);
00181 H5Pset_fapl_mpio(plist_id, comm, info);
00182 hid_t file_id = H5Fopen(filename.c_str(), H5F_ACC_RDWR, plist_id);
00183 CHECK_ERROR(file_id,"Error opening hdf5 file.");
00184 H5Pclose(plist_id);
00185 hid_t dataset_id;
00186 #if H5Dopen_vers == 2
00187 dataset_id = H5Dopen2(file_id, name.c_str(), H5P_DEFAULT);
00188 #else
00189 dataset_id = H5Dopen(file_id, name.c_str());
00190 #endif
00191 CHECK_ERROR(dataset_id,"Error opening dataset in file.");
00192
00193 hid_t space_id = H5Dget_space(dataset_id);
00194 hsize_t dims[2];
00195 H5Sget_simple_extent_dims(space_id, dims, NULL);
00196
00197 hsize_t count[2];
00198 hsize_t offset[2];
00199
00200 hsize_t item_cnt = dims[0]/mpi_size+(dims[0]%mpi_size==0 ? 0 : 1);
00201 hsize_t cnt = (mpi_rank<mpi_size-1 ? item_cnt : dims[0]-item_cnt*(mpi_size-1));
00202
00203 count[0] = cnt;
00204 count[1] = dims[1];
00205 offset[0] = mpi_rank*item_cnt;
00206 offset[1] = 0;
00207
00208 hid_t memspace_id = H5Screate_simple(2,count,NULL);
00209
00210 H5Sselect_hyperslab(space_id, H5S_SELECT_SET, offset, NULL, count, NULL);
00211
00212 dataset.rows = count[0];
00213 dataset.cols = count[1];
00214 dataset.data = new T[dataset.rows*dataset.cols];
00215
00216 plist_id = H5Pcreate(H5P_DATASET_XFER);
00217 H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE);
00218 status = H5Dread(dataset_id, get_hdf5_type<T>(), memspace_id, space_id, plist_id, dataset.data);
00219 CHECK_ERROR(status, "Error reading dataset");
00220
00221 H5Pclose(plist_id);
00222 H5Sclose(space_id);
00223 H5Sclose(memspace_id);
00224 H5Dclose(dataset_id);
00225 H5Fclose(file_id);
00226 }
00227 }
00228 #endif // HAVE_MPI
00229 }
00230
00231 #endif