Field3D
|
00001 //----------------------------------------------------------------------------// 00002 00003 /* 00004 * Copyright (c) 2009 Sony Pictures Imageworks Inc 00005 * 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 00012 * Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the 00017 * distribution. Neither the name of Sony Pictures Imageworks nor the 00018 * names of its contributors may be used to endorse or promote 00019 * products derived from this software without specific prior written 00020 * permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00025 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00026 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00027 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00028 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00029 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 00031 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00032 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 00033 * OF THE POSSIBILITY OF SUCH DAMAGE. 00034 */ 00035 00036 //----------------------------------------------------------------------------// 00037 00042 //----------------------------------------------------------------------------// 00043 00044 #ifndef _INCLUDED_Field3D_SparseDataReader_H_ 00045 #define _INCLUDED_Field3D_SparseDataReader_H_ 00046 00047 //----------------------------------------------------------------------------// 00048 00049 #include <hdf5.h> 00050 #include <string.h> // for memcpy 00051 #include "Hdf5Util.h" 00052 00053 //----------------------------------------------------------------------------// 00054 00055 #include "ns.h" 00056 00057 FIELD3D_NAMESPACE_OPEN 00058 00059 //----------------------------------------------------------------------------// 00060 // SparseDataReader 00061 //----------------------------------------------------------------------------// 00062 00067 template <class Data_T> 00068 class SparseDataReader 00069 { 00070 public: 00071 00072 // Constructors -------------------------------------------------------------- 00073 00076 SparseDataReader(hid_t location, int valuesPerBlock, int occupiedBlocks); 00077 00078 // Main methods -------------------------------------------------------------- 00079 00082 void readBlock(int idx, Data_T &result); 00083 00086 void readBlockList(int idx, const std::vector<Data_T*>& memoryList); 00087 00088 private: 00089 00090 // Data members -------------------------------------------------------------- 00091 00092 Hdf5Util::H5ScopedDopen m_dataSet; 00093 Hdf5Util::H5ScopedDget_space m_fileDataSpace; 00094 Hdf5Util::H5ScopedDget_type m_dataType; 00095 Hdf5Util::H5ScopedScreate m_memDataSpace; 00096 00097 int m_valuesPerBlock; 00098 00099 const std::string k_dataStr; 00100 }; 00101 00102 //----------------------------------------------------------------------------// 00103 // SparseDataReader implementations 00104 //----------------------------------------------------------------------------// 00105 00106 template <class Data_T> 00107 SparseDataReader<Data_T>::SparseDataReader(hid_t location, int valuesPerBlock, 00108 int occupiedBlocks) 00109 : m_valuesPerBlock(valuesPerBlock), 00110 k_dataStr("data") 00111 { 00112 using namespace Hdf5Util; 00113 using namespace Exc; 00114 00115 hsize_t dims[2]; 00116 hsize_t memDims[1]; 00117 00118 // Open the data set 00119 m_dataSet.open(location, k_dataStr, H5P_DEFAULT); 00120 if (m_dataSet.id() < 0) 00121 throw OpenDataSetException("Couldn't open data set: " + k_dataStr); 00122 00123 // Get the space and type 00124 m_fileDataSpace.open(m_dataSet.id()); 00125 m_dataType.open(m_dataSet.id()); 00126 if (m_fileDataSpace.id() < 0) 00127 throw GetDataSpaceException("Couldn't get data space"); 00128 if (m_dataType.id() < 0) 00129 throw GetDataTypeException("Couldn't get data type"); 00130 00131 // Make the memory data space 00132 memDims[0] = m_valuesPerBlock; 00133 m_memDataSpace.create(H5S_SIMPLE); 00134 H5Sset_extent_simple(m_memDataSpace.id(), 1, memDims, NULL); 00135 00136 // Get the dimensions and check they match 00137 H5Sget_simple_extent_dims(m_fileDataSpace.id(), dims, NULL); 00138 if (dims[1] != static_cast<hsize_t>(m_valuesPerBlock)) { 00139 throw FileIntegrityException("Block length mismatch in " 00140 "SparseDataReader"); 00141 } 00142 if (dims[0] != static_cast<hsize_t>(occupiedBlocks)) 00143 throw FileIntegrityException("Block count mismatch in " 00144 "SparseDataReader"); 00145 } 00146 00147 //----------------------------------------------------------------------------// 00148 00149 template <class Data_T> 00150 void SparseDataReader<Data_T>::readBlock(int idx, Data_T &result) 00151 { 00152 using namespace Hdf5Util; 00153 using namespace Exc; 00154 00155 hsize_t offset[2]; 00156 hsize_t count[2]; 00157 herr_t status; 00158 00159 offset[0] = idx; // Index of block 00160 offset[1] = 0; // Index of first data in block. Always 0 00161 count[0] = 1; // Number of columns to read. Always 1 00162 count[1] = m_valuesPerBlock; // Number of values in one column 00163 00164 status = H5Sselect_hyperslab(m_fileDataSpace.id(), H5S_SELECT_SET, 00165 offset, NULL, count, NULL); 00166 if (status < 0) { 00167 throw ReadHyperSlabException("Couldn't select slab " + 00168 boost::lexical_cast<std::string>(idx)); 00169 } 00170 00171 status = H5Dread(m_dataSet.id(), DataTypeTraits<Data_T>::h5type(), 00172 m_memDataSpace.id(), m_fileDataSpace.id(), 00173 H5P_DEFAULT, &result); 00174 } 00175 00176 //----------------------------------------------------------------------------// 00177 00178 template <class Data_T> 00179 void SparseDataReader<Data_T>::readBlockList 00180 (int idxLo, const std::vector<Data_T*>& memoryList) 00181 { 00182 using namespace Hdf5Util; 00183 using namespace Exc; 00184 00185 hsize_t offset[2]; 00186 hsize_t count[2]; 00187 herr_t status; 00188 00189 offset[0] = idxLo; // Index of block 00190 offset[1] = 0; // Index of first data in block. Always 0 00191 count[0] = memoryList.size(); // Number of columns to read. 00192 count[1] = m_valuesPerBlock; // Number of values in one column 00193 00194 status = H5Sselect_hyperslab(m_fileDataSpace.id(), H5S_SELECT_SET, 00195 offset, NULL, count, NULL); 00196 if (status < 0) { 00197 throw ReadHyperSlabException("Couldn't select slab " + 00198 boost::lexical_cast<std::string>(idxLo)); 00199 } 00200 00201 // Make the memory data space --- 00202 00203 Hdf5Util::H5ScopedScreate localMemDataSpace; 00204 hsize_t memDims[2]; 00205 memDims[0] = memoryList.size(); 00206 memDims[1] = m_valuesPerBlock; 00207 localMemDataSpace.create(H5S_SIMPLE); 00208 H5Sset_extent_simple(localMemDataSpace.id(), 2, memDims, NULL); 00209 00210 // Setup the temporary memory region --- 00211 00212 int bytesPerValue = 0; 00213 { 00214 hid_t t = DataTypeTraits<Data_T>::h5type(); 00215 if (t == H5T_NATIVE_CHAR) 00216 bytesPerValue = 1; 00217 else if (t == H5T_NATIVE_SHORT) 00218 bytesPerValue = 2; 00219 else if (t == H5T_NATIVE_FLOAT) 00220 bytesPerValue = 4; 00221 else if (t == H5T_NATIVE_DOUBLE) 00222 bytesPerValue = 8; 00223 } 00224 00225 int dim = sizeof(Data_T) / bytesPerValue; 00226 std::vector<Data_T> bigblock(memoryList.size() * m_valuesPerBlock/dim); 00227 00228 status = H5Dread(m_dataSet.id(), 00229 DataTypeTraits<Data_T>::h5type(), 00230 localMemDataSpace.id(), 00231 m_fileDataSpace.id(), 00232 H5P_DEFAULT, &bigblock[0]); 00233 00234 if (status < 0) { 00235 throw Hdf5DataReadException("Couldn't read slab " + 00236 boost::lexical_cast<std::string>(idxLo)); 00237 } 00238 00239 // Distribute block data into memory slots --- 00240 for (size_t i = 0; i < memoryList.size(); ++i) { 00241 memcpy(memoryList[i], 00242 &bigblock[i * m_valuesPerBlock / dim], 00243 bytesPerValue * m_valuesPerBlock); 00244 } 00245 } 00246 00247 //----------------------------------------------------------------------------// 00248 00249 FIELD3D_NAMESPACE_HEADER_CLOSE 00250 00251 //----------------------------------------------------------------------------// 00252 00253 #endif