| kspaceFirstOrder3D-CUDA 1.1 The CUDA/C++ implementation of the k-wave toolbox for the time-domain simulation of acoustic wave fields in 3D

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
IndexOutputHDF5Stream.cpp
Go to the documentation of this file.
1 /**
2 * @file IndexOutputHDF5Stream.cpp
3 *
4 * @author Jiri Jaros \n
5 * Faculty of Information Technology \n
6 * Brno University of Technology \n
7 * jarosjir@fit.vutbr.cz
8 *
9 * @brief The implementation file of the class saving data based on index senor mask into
10 * the output HDF5 file.
11 *
12 * @version kspaceFirstOrder3D 3.4
13 *
14 * @date 29 August 2014, 10:10 (created)
15 * 29 July 2016, 16:56 (revised)
16 *
17 * @section License
18 * This file is part of the C++ extension of the k-Wave Toolbox
19 * (http://www.k-wave.org).\n Copyright (C) 2016 Jiri Jaros and Bradley Treeby.
20 *
21 * This file is part of the k-Wave. k-Wave is free software: you can redistribute it and/or modify
22 * it under the terms of the GNU Lesser General Public License as published by the Free Software
23 * Foundation, either version 3 of the License, or (at your option) any later version.
24 *
25 * k-Wave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
26 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
27 * General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public License along with k-Wave.
30 * If not, see http://www.gnu.org/licenses/.
31 */
32
33 #include <OutputHDF5Streams/IndexOutputHDF5Stream.h>
34 #include <OutputHDF5Streams/OutputStreamsCUDAKernels.cuh>
35
36 #include <Parameters/Parameters.h>
37 #include <Logger/Logger.h>
38
39 //------------------------------------------------------------------------------------------------//
40 //------------------------------------------ Constants -------------------------------------------//
41 //------------------------------------------------------------------------------------------------//
42
43 //------------------------------------------------------------------------------------------------//
44 //--------------------------------------- Public methods -----------------------------------------//
45 //------------------------------------------------------------------------------------------------//
46
47
48 /**
49 * Constructor - links the HDF5 dataset, source (sampled matrix), sensor mask and the reduce
50 * operator together. The constructor DOES NOT allocate memory because the size of the sensor mask
51 * is not known at the time the instance of the class is being created.
52 *
53 * @param [in] file - Handle to the HDF5 (output) file
54 * @param [in] datasetName - The dataset's name (index based sensor data stored in a single dataset)
55 * @param [in] sourceMatrix - The source matrix (only real matrices are supported)
56 * @param [in] sensorMask - Index based sensor mask
57 * @param [in] reduceOp - Reduce operator
58 */
59 TIndexOutputHDF5Stream::TIndexOutputHDF5Stream(THDF5_File& file,
60 TMatrixName& datasetName,
61 const TRealMatrix& sourceMatrix,
62 const TIndexMatrix& sensorMask,
63 const TReduceOperator reduceOp)
64 : TBaseOutputHDF5Stream(file, datasetName, sourceMatrix, reduceOp),
65 sensorMask(sensorMask),
66 dataset(H5I_BADID),
67 sampledTimeStep(0),
68 eventSamplingFinished()
69 {
70 // Create event for sampling
71 checkCudaErrors(cudaEventCreate(&eventSamplingFinished));
72 }// end of TIndexOutputHDF5Stream
73 //--------------------------------------------------------------------------------------------------
74
75 /**
76 * Destructor.
77 * If the file is still opened, it applies the post processing and flush the data.
78 * Then, the object memory is freed and the object destroyed.
79 */
80 TIndexOutputHDF5Stream::~TIndexOutputHDF5Stream()
81 {
82 // Destroy sampling event
83 checkCudaErrors(cudaEventDestroy(eventSamplingFinished));
84
85 Close();
86 // free memory
87 FreeMemory();
88 }// end of Destructor
89 //--------------------------------------------------------------------------------------------------
90
91 /**
92 * Create a HDF5 stream, create a dataset, and allocate data for it.
93 */
94 void TIndexOutputHDF5Stream::Create()
95 {
96
97 size_t nSampledElementsPerStep = sensorMask.GetElementCount();
98
99 const TParameters& params = TParameters::GetInstance();
100
101 // Derive dataset dimension sizes
102 TDimensionSizes datasetSize(nSampledElementsPerStep,
103 (reduceOp == NONE) ? params.Get_nt() - params.GetStartTimeIndex() : 1,
104 1);
105
106 // Set HDF5 chunk size
107 TDimensionSizes chunkSize(nSampledElementsPerStep, 1, 1);
108 // for chunks bigger than 32 MB
109 if (nSampledElementsPerStep > (CHUNK_SIZE_4MB * 8))
110 {
111 chunkSize.nx = CHUNK_SIZE_4MB; // set chunk size to MB
112 }
113
114 // Create a dataset under the root group
115 dataset = file.CreateFloatDataset(file.GetRootGroup(),
116 rootObjectName,
117 datasetSize,
118 chunkSize,
119 params.GetCompressionLevel());
120
121 // Write dataset parameters
122 file.WriteMatrixDomainType(file.GetRootGroup(), rootObjectName, THDF5_File::REAL);
123 file.WriteMatrixDataType (file.GetRootGroup(), rootObjectName, THDF5_File::FLOAT);
124
125 // Sampled time step
126 sampledTimeStep = 0;
127
128 // Set buffer size
129 bufferSize = nSampledElementsPerStep;
130
131 // Allocate memory
132 AllocateMemory();
133 }// end of Create
134 //--------------------------------------------------------------------------------------------------
135
136 /**
137 * Reopen the output stream after restart.
138 *
139 */
140 void TIndexOutputHDF5Stream::Reopen()
141 {
142 // Get parameters
143 const TParameters& params = TParameters::GetInstance();
144
145 // Set buffer size
146 bufferSize = sensorMask.GetElementCount();
147
148 // Allocate memory
149 AllocateMemory();
150
151 // Reopen the dataset
152 dataset = file.OpenDataset(file.GetRootGroup(), rootObjectName);
153
154
155 if (reduceOp == NONE)
156 { // raw time series - just seek to the right place in the dataset
157 sampledTimeStep = (params.Get_t_index() < params.GetStartTimeIndex()) ?
158 0 : (params.Get_t_index() - params.GetStartTimeIndex());
159
160 }
161 else
162 { // aggregated quantities - reload data
163 sampledTimeStep = 0;
164
165 // Read data from disk only if there were anything stored there (t_index >= start_index)
166 if (TParameters::GetInstance().Get_t_index() > TParameters::GetInstance().GetStartTimeIndex())
167 {
168 // Since there is only a single timestep in the dataset, I can read the whole dataset
169 file.ReadCompleteDataset(file.GetRootGroup(),
170 rootObjectName,
171 TDimensionSizes(bufferSize, 1, 1),
172 hostBuffer);
173
174 // Send data to device
175 CopyDataToDevice();
176 }
177 }
178 }// end of Reopen
179 //--------------------------------------------------------------------------------------------------
180
181
182 /**
183 * Sample grid points, line them up in the buffer, if necessary a reduce operator is applied.
184 *
185 * @warning data is not flushed, there is no sync.
186 */
187 void TIndexOutputHDF5Stream::Sample()
188 {
189 switch (reduceOp)
190 {
191 case NONE :
192 {
193 OutputStreamsCUDAKernels::SampleIndex<NONE>
194 (deviceBuffer,
195 sourceMatrix.GetDeviceData(),
196 sensorMask.GetDeviceData(),
197 sensorMask.GetElementCount());
198
199 // Record an event when the data has been copied over.
200 checkCudaErrors(cudaEventRecord(eventSamplingFinished));
201
202 break;
203 }// case NONE
204
205 case RMS :
206 {
207 OutputStreamsCUDAKernels::SampleIndex<RMS>
208 (deviceBuffer,
209 sourceMatrix.GetDeviceData(),
210 sensorMask.GetDeviceData(),
211 sensorMask.GetElementCount());
212
213 break;
214 }// case RMS
215
216 case MAX :
217 {
218 OutputStreamsCUDAKernels::SampleIndex<MAX>
219 (deviceBuffer,
220 sourceMatrix.GetDeviceData(),
221 sensorMask.GetDeviceData(),
222 sensorMask.GetElementCount());
223 break;
224 }// case MAX
225
226 case MIN :
227 {
228 OutputStreamsCUDAKernels::SampleIndex<MIN>
229 (deviceBuffer,
230 sourceMatrix.GetDeviceData(),
231 sensorMask.GetDeviceData(),
232 sensorMask.GetElementCount());
233 break;
234 } //case MIN
235 }// switch
236 }// end of Sample
237 //--------------------------------------------------------------------------------------------------
238
239
240 /**
241 * Flush data for the timestep. Only applicable on RAW data series.
242 */
243 void TIndexOutputHDF5Stream::FlushRaw()
244 {
245 if (reduceOp == NONE)
246 {
247 // make sure the data has been copied from the GPU
248 cudaEventSynchronize(eventSamplingFinished);
249
250 // only raw time series are flushed down to the disk every time step
251 FlushBufferToFile();
252 }
253 }// end of FlushRaw
254 //--------------------------------------------------------------------------------------------------
255
256
257 /**
258 * Apply post-processing on the buffer and flush it to the file.
259 */
260 void TIndexOutputHDF5Stream::PostProcess()
261 {
262 // run inherited method
263 TBaseOutputHDF5Stream::PostProcess();
264
265 // When no reduction operator is applied, the data is flushed after every time step
266 // which means it has been done before
267 if (reduceOp != NONE)
268 {
269 // Copy data from GPU matrix
270 CopyDataFromDevice();
271 // flush to disk
272 FlushBufferToFile();
273 }
274 }// end of PostProcessing
275 //-------------------------------------------------------------------------------------------------
276
277
278 /**
279 * Checkpoint the stream and close.
280 *
281 */
282 void TIndexOutputHDF5Stream::Checkpoint()
283 {
284 // raw data has already been flushed, others has to be flushed here
285 if (reduceOp != NONE)
286 {
287 // copy data from the device
288 CopyDataFromDevice();
289 // flush to disk
290 FlushBufferToFile();
291 }
292 }// end of Checkpoint
293 //--------------------------------------------------------------------------------------------------
294
295 /**
296 * Close stream (apply post-processing if necessary, flush data and close).
297 */
298 void TIndexOutputHDF5Stream::Close()
299 {
300 // the dataset is still opened
301 if (dataset != H5I_BADID)
302 {
303 file.CloseDataset(dataset);
304 }
305
306 dataset = H5I_BADID;
307 }// end of Close
308 //--------------------------------------------------------------------------------------------------
309
310 //------------------------------------------------------------------------------------------------//
311 //-------------------------------------- Protected methods ---------------------------------------//
312 //------------------------------------------------------------------------------------------------//
313
314
315 /**
316 * Flush the buffer down to the file at the actual position
317 */
318 void TIndexOutputHDF5Stream::FlushBufferToFile()
319 {
320 file.WriteHyperSlab(dataset,
321 TDimensionSizes(0,sampledTimeStep,0),
322 TDimensionSizes(bufferSize,1,1),
323 hostBuffer);
324 sampledTimeStep++;
325 }// end of FlushToFile
326 //--------------------------------------------------------------------------------------------------
327
328 //------------------------------------------------------------------------------------------------//
329 //--------------------------------------- Private methods ----------------------------------------//
330 //------------------------------------------------------------------------------------------------//
331
TBaseOutputHDF5Stream::file
THDF5_File & file
HDF5 file handle.
Definition: BaseOutputHDF5Stream.h:115
THDF5_File::CreateFloatDataset
hid_t CreateFloatDataset(const hid_t parentGroup, TMatrixName &datasetName, const TDimensionSizes &dimensionSizes, const TDimensionSizes &chunkSizes, const size_t compressionLevel)
Create a float HDF5 dataset at a specified place in the file tree (3D/4D).
Definition: HDF5_File.cpp:296
TParameters::GetStartTimeIndex
size_t GetStartTimeIndex() const
Get start time index for sensor recording.
Definition: Parameters.h:225
THDF5_File::WriteMatrixDomainType
void WriteMatrixDomainType(const hid_t parentGroup, TMatrixName &datasetName, const TMatrixDomainType &matrixDomainType)
Write matrix domain type into the dataset under the root group.
Definition: HDF5_File.cpp:1048
TBaseIndexMatrix::GetDeviceData
virtual size_t * GetDeviceData()
Get raw GPU data out of the class (for direct GPU kernel access).
Definition: BaseIndexMatrix.h:92
TBaseOutputHDF5Stream::CopyDataFromDevice
virtual void CopyDataFromDevice()
Copy data deviceBuffer -> hostBuffer.
Definition: BaseOutputHDF5Stream.cpp:245
TBaseOutputHDF5Stream::RMS
calculate root mean square
Definition: BaseOutputHDF5Stream.h:59
TBaseOutputHDF5Stream::rootObjectName
std::string rootObjectName
Dataset name.
Definition: BaseOutputHDF5Stream.h:118
TParameters::GetInstance
static TParameters & GetInstance()
Get instance of the singleton class.
Definition: Parameters.cpp:70
TBaseOutputHDF5Stream::reduceOp
const TReduceOperator reduceOp
Reduce operator.
Definition: BaseOutputHDF5Stream.h:126
TIndexOutputHDF5Stream::Reopen
virtual void Reopen()
Reopen the output stream after restart and reload data.
Definition: IndexOutputHDF5Stream.cpp:140
TIndexOutputHDF5Stream::Sample
virtual void Sample()
Sample data into buffer, apply reduction or copy to the CPU side.
Definition: IndexOutputHDF5Stream.cpp:187
Parameters.h
The header file containing the parameters of the simulation.
OutputStreamsCUDAKernels.cuh
The header file of cuda kernels used for data sampling (output streams).
TBaseOutputHDF5Stream::CHUNK_SIZE_4MB
static const size_t CHUNK_SIZE_4MB
chunk size of 4MB in number of float elements
Definition: BaseOutputHDF5Stream.h:140
TMatrixName
const std::string TMatrixName
Datatype for matrix names.
Definition: MatrixNames.h:45
TBaseOutputHDF5Stream::MIN
store minimum
Definition: BaseOutputHDF5Stream.h:63
checkCudaErrors
#define checkCudaErrors(val)
Macro checking cuda errors and printing the file name and line. Inspired by CUDA common checking rout...
Definition: Logger.h:209
TBaseOutputHDF5Stream::PostProcess
virtual void PostProcess()
Apply post-processing on the buffer and flush it to the file.
Definition: BaseOutputHDF5Stream.cpp:80
TBaseOutputHDF5Stream::AllocateMemory
virtual void AllocateMemory()
A generic function to allocate memory - not used in the base class.
Definition: BaseOutputHDF5Stream.cpp:124
THDF5_File::WriteMatrixDataType
void WriteMatrixDataType(const hid_t parentGroup, TMatrixName &datasetName, const TMatrixDataType &matrixDataType)
Write matrix data type into the dataset under a specified group.
Definition: HDF5_File.cpp:1029
TBaseOutputHDF5Stream::sourceMatrix
const TRealMatrix & sourceMatrix
Source matrix to be sampled.
Definition: BaseOutputHDF5Stream.h:121
TParameters::Get_t_index
size_t Get_t_index() const
Get simulation time step.
Definition: Parameters.h:102
TIndexOutputHDF5Stream::TIndexOutputHDF5Stream
TIndexOutputHDF5Stream(THDF5_File &file, TMatrixName &datasetName, const TRealMatrix &sourceMatrix, const TIndexMatrix &sensorMask, const TReduceOperator reduceOp)
Constructor.
Definition: IndexOutputHDF5Stream.cpp:59
TIndexOutputHDF5Stream::Checkpoint
virtual void Checkpoint()
Checkpoint the stream.
Definition: IndexOutputHDF5Stream.cpp:282
TIndexOutputHDF5Stream::FlushBufferToFile
virtual void FlushBufferToFile()
Flush the buffer to the file.
Definition: IndexOutputHDF5Stream.cpp:318
Logger.h
The header file containing a class responsible for printing out info and error messages (stdout...
TParameters
Class storing all parameters of the simulation.
Definition: Parameters.h:49
THDF5_File::GetRootGroup
hid_t GetRootGroup() const
Get handle to the root group.
Definition: HDF5_File.h:573
TBaseOutputHDF5Stream::TReduceOperator
TReduceOperator
How to aggregate data.
Definition: BaseOutputHDF5Stream.h:54
TBaseOutputHDF5Stream::deviceBuffer
float * deviceBuffer
Temporary buffer on the GPU side - only for aggregated quantities.
Definition: BaseOutputHDF5Stream.h:137
TBaseOutputHDF5Stream::NONE
store actual data (time series)
Definition: BaseOutputHDF5Stream.h:57
TIndexOutputHDF5Stream::eventSamplingFinished
cudaEvent_t eventSamplingFinished
Has the sampling finished?
Definition: IndexOutputHDF5Stream.h:98
TBaseOutputHDF5Stream
Abstract base class for output data streams (sampled data).
Definition: BaseOutputHDF5Stream.h:46
TIndexOutputHDF5Stream::Close
virtual void Close()
Close stream (apply post-processing if necessary, flush data and close).
Definition: IndexOutputHDF5Stream.cpp:298
TBaseOutputHDF5Stream::FreeMemory
virtual void FreeMemory()
A generic function to free memory - not used in the base class.
Definition: BaseOutputHDF5Stream.cpp:209
TBaseIndexMatrix::GetElementCount
virtual size_t GetElementCount() const
Get total element count of the matrix.
Definition: BaseIndexMatrix.h:65
TIndexOutputHDF5Stream::dataset
hid_t dataset
Handle to a HDF5 dataset.
Definition: IndexOutputHDF5Stream.h:92
TRealMatrix
The class for real matrices.
Definition: RealMatrix.h:45
TBaseOutputHDF5Stream::hostBuffer
float * hostBuffer
Temporary buffer for store on the GPU side.
Definition: BaseOutputHDF5Stream.h:135
TBaseOutputHDF5Stream::CopyDataToDevice
virtual void CopyDataToDevice()
Copy data hostBuffer-> deviceBuffer.
Definition: BaseOutputHDF5Stream.cpp:231
TIndexMatrix
The class for 64b unsigned integers (indices). It is used for sensor_mask_index or sensor_corners_mas...
Definition: IndexMatrix.h:46
IndexOutputHDF5Stream.h
The header file of the class saving data based on the index senor mask into the output HDF5 file...
TIndexOutputHDF5Stream::FlushRaw
virtual void FlushRaw()
Flush data to disk (from raw streams only).
Definition: IndexOutputHDF5Stream.cpp:243
TParameters::GetCompressionLevel
size_t GetCompressionLevel() const
Get compression level.
Definition: Parameters.h:218
TBaseOutputHDF5Stream::MAX
store maximum
Definition: BaseOutputHDF5Stream.h:61
THDF5_File::WriteHyperSlab
void WriteHyperSlab(const hid_t dataset, const TDimensionSizes &position, const TDimensionSizes &size, const float *data)
Write a hyper-slab into the dataset - float dataset.
Definition: HDF5_File.cpp:473
TBaseFloatMatrix::GetDeviceData
virtual float * GetDeviceData()
Get raw GPU data out of the class (for direct GPU kernel access).
Definition: BaseFloatMatrix.h:95
TBaseOutputHDF5Stream::bufferSize
size_t bufferSize
Buffer size.
Definition: BaseOutputHDF5Stream.h:132
TIndexOutputHDF5Stream::sampledTimeStep
size_t sampledTimeStep
Time step to store (N/A for aggregated)
Definition: IndexOutputHDF5Stream.h:95
THDF5_File::ReadCompleteDataset
void ReadCompleteDataset(const hid_t parentGroup, TMatrixName &datasetName, const TDimensionSizes &dimensionSizes, float *data)
Read data from the dataset under a specified group, float dataset.
Definition: HDF5_File.cpp:887
TParameters::Get_nt
size_t Get_nt() const
Get Nt value.
Definition: Parameters.h:100
TIndexOutputHDF5Stream::PostProcess
virtual void PostProcess()
Apply post-processing on the buffer and flush it to the file.
Definition: IndexOutputHDF5Stream.cpp:260
THDF5_File::CloseDataset
void CloseDataset(const hid_t dataset)
Close the HDF5 dataset.
Definition: HDF5_File.cpp:457
TIndexOutputHDF5Stream::~TIndexOutputHDF5Stream
virtual ~TIndexOutputHDF5Stream()
Destructor.
Definition: IndexOutputHDF5Stream.cpp:80
THDF5_File
Class wrapping the HDF5 routines.
Definition: HDF5_File.h:500
TIndexOutputHDF5Stream::Create
virtual void Create()
Create a HDF5 stream and allocate data for it.
Definition: IndexOutputHDF5Stream.cpp:94
TIndexOutputHDF5Stream::sensorMask
const TIndexMatrix & sensorMask
Sensor mask to sample data.
Definition: IndexOutputHDF5Stream.h:89
TDimensionSizes
Structure with 4D dimension sizes (3 in space and 1 in time).
Definition: DimensionSizes.h:66
THDF5_File::OpenDataset
hid_t OpenDataset(const hid_t parentGroup, TMatrixName &datasetName)
Open the HDF5 dataset at a specified place in the file tree.
Definition: HDF5_File.cpp:268