kspaceFirstOrder3D-OMP  1.2
The C++ implementation of the k-wave toolbox for the time-domain simulation of acoustic wave fields in 3D
IndexOutputStream.cpp
Go to the documentation of this file.
1 /**
2  * @file IndexOutputStream.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 2.16
13  *
14  * @date 26 August 2017, 17:03 (created) \n
15  * 04 September 2017, 11:10 (revised)
16  *
17  * @copyright Copyright (C) 2017 Jiri Jaros and Bradley Treeby.
18  *
19  * This file is part of the C++ extension of the [k-Wave Toolbox](http://www.k-wave.org).
20  *
21  * This file is part of the k-Wave. k-Wave is free software: you can redistribute it and/or modify it under the terms
22  * of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the
23  * 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 the implied
26  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
27  * 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/](http://www.gnu.org/licenses/).
31  */
32 
33 #include <algorithm>
34 
36 #include <Parameters/Parameters.h>
37 
38 
39 
40 //--------------------------------------------------------------------------------------------------------------------//
41 //---------------------------------------------------- Constants -----------------------------------------------------//
42 //--------------------------------------------------------------------------------------------------------------------//
43 
44 
45 //--------------------------------------------------------------------------------------------------------------------//
46 //------------------------------------------------- Public methods ---------------------------------------------------//
47 //--------------------------------------------------------------------------------------------------------------------//
48 
49 /**
50  * Constructor - links the HDF5 dataset, SourceMatrix, and SensorMask together.
51  */
53  MatrixName& datasetName,
54  const RealMatrix& sourceMatrix,
55  const IndexMatrix& sensorMask,
56  const ReduceOperator reduceOp,
57  float * bufferToReuse)
58  : BaseOutputStream(file, datasetName, sourceMatrix, reduceOp, bufferToReuse),
59  sensorMask(sensorMask),
60  mDataset(H5I_BADID),
61  mSampledTimeStep(0)
62 {
63 
64 }// end of IndexOutputStream
65 //----------------------------------------------------------------------------------------------------------------------
66 
67 /**
68  * Destructor.
69  */
71 {
72  close();
73  // free memory only if it was allocated
74  if (!mBufferReuse) freeMemory();
75 }// end of Destructor
76 //----------------------------------------------------------------------------------------------------------------------
77 
78 /**
79  * Create a HDF5 stream, create a dataset, and allocate data for it.
80  */
82 {
83  size_t nSampledElementsPerStep = sensorMask.size();
84 
85  const Parameters& params = Parameters::getInstance();
86 
87  // Derive dataset dimension sizes
88  DimensionSizes datasetSize(nSampledElementsPerStep,
90  params.getNt() - params.getSamplingStartTimeIndex() : 1,
91  1);
92 
93  // Set HDF5 chunk size
94  DimensionSizes chunkSize(nSampledElementsPerStep, 1, 1);
95  // for data bigger than 32 MB
96  if (nSampledElementsPerStep > (kChunkSize4MB * 8))
97  {
98  chunkSize.nx = kChunkSize4MB; // set chunk size to MB
99  }
100 
101  // Create a dataset under the root group
104  datasetSize,
105  chunkSize,
107  params.getCompressionLevel());
108 
109  // Write dataset parameters
112 
113  // Sampled time step
114  mSampledTimeStep = 0;
115 
116  // Set buffer size
117  mBufferSize = nSampledElementsPerStep;
118 
119  // Allocate memory if needed
121 }// end of create
122 //----------------------------------------------------------------------------------------------------------------------
123 
124 /**
125  * Reopen the output stream after restart.
126  */
128 {
129  // Get parameters
130  const Parameters& params = Parameters::getInstance();
131 
132  // Set buffer size
134 
135  // Allocate memory if needed
137 
138  // Reopen the dataset
140 
142  { // raw time series - just seek to the right place in the dataset
144  0 : (params.getTimeIndex() - params.getSamplingStartTimeIndex());
145  }
146  else
147  { // aggregated quantities - reload data
148  mSampledTimeStep = 0;
149  // read only if it is necessary (it is anything to read).
150  if (params.getTimeIndex() > params.getSamplingStartTimeIndex())
151  {
152  // Since there is only a single timestep in the dataset, I can read the whole dataset
156  mStoreBuffer);
157  }
158  }
159 }// end of reopen
160 //----------------------------------------------------------------------------------------------------------------------
161 
162 /**
163  * Sample grid points, line them up in the buffer an flush to the disk unless a reduction operator is applied.
164  */
166 {
167  const float* sourceData = mSourceMatrix.getData();
168  const size_t* sensorData = sensorMask.getData();
169 
170  switch (mReduceOp)
171  {
172  case ReduceOperator::kNone :
173  {
174  #pragma omp parallel for
175  for (size_t i = 0; i < mBufferSize; i++)
176  {
177  mStoreBuffer[i] = sourceData[sensorData[i]];
178  }
179  // only raw time series are flushed down to the disk every time step
181  /* - for future use when offloading the sampling work to HDF5 - now it seem to be slower
182  HDF5_File.WriteSensorbyMaskToHyperSlab(HDF5_DatasetId,
183  Position, // position in the dataset
184  BufferSize, // number of elements sampled
185  SensorMask.GetRawData(), // Sensor
186  SourceMatrix.GetDimensionSizes(), // Matrix dims
187  SourceMatrix.GetRawData());
188  Position.Y++;
189  */
190  break;
191  }// case kNone
192 
193  case ReduceOperator::kRms :
194  {
195  #pragma omp parallel for
196  for (size_t i = 0; i < mBufferSize; i++)
197  {
198  mStoreBuffer[i] += (sourceData[sensorData[i]] * sourceData[sensorData[i]]);
199  }
200  break;
201  }// case kRms
202 
203  case ReduceOperator::kMax :
204  {
205  #pragma omp parallel for
206  for (size_t i = 0; i < mBufferSize; i++)
207  {
208  mStoreBuffer[i] = std::max(mStoreBuffer[i], sourceData[sensorData[i]]);
209  }
210  break;
211  }// case kMax
212 
213  case ReduceOperator::kMin :
214  {
215  #pragma omp parallel for
216  for (size_t i = 0; i < mBufferSize; i++)
217  {
218  mStoreBuffer[i] = std::min(mStoreBuffer[i], sourceData[sensorData[i]]);
219  }
220  break;
221  } //case kMin
222  }// switch
223 }// end of sample
224 //----------------------------------------------------------------------------------------------------------------------
225 
226 /**
227  * Apply post-processing on the buffer and flush it to the file.
228  */
230 {
231  // run inherited method
233  // When no reduction operator is applied, the data is flushed after every time step
235  {
237  }
238 }// end of postProcessing
239 //----------------------------------------------------------------------------------------------------------------------
240 
241 /**
242  * Checkpoint the stream and close.
243  */
245 {
246  // raw data has already been flushed, others has to be flushed here
248  {
250  }
251 }// end of checkpoint
252 //----------------------------------------------------------------------------------------------------------------------
253 
254 /**
255  * Close stream (apply post-processing if necessary, flush data and close).
256  */
258 {
259  // the dataset is still opened
260  if (mDataset != H5I_BADID)
261  {
263  }
264 
265  mDataset = H5I_BADID;
266 }// end of close
267 //----------------------------------------------------------------------------------------------------------------------
268 
269 //--------------------------------------------------------------------------------------------------------------------//
270 //------------------------------------------------ Protected methods -------------------------------------------------//
271 //--------------------------------------------------------------------------------------------------------------------//
272 
273 
274 
275 /**
276  * Flush the buffer down to the file at the actual position.
277  */
279 {
283  mStoreBuffer);
285 }// end of flushToFile
286 //----------------------------------------------------------------------------------------------------------------------
287 
288 //--------------------------------------------------------------------------------------------------------------------//
289 //------------------------------------------------- Private methods --------------------------------------------------//
290 //--------------------------------------------------------------------------------------------------------------------//
291 
virtual void reopen()
Reopen the output stream after restart and reload data.
hid_t openDataset(const hid_t parentGroup, MatrixName &datasetName)
Open a dataset at a specified place in the file tree.
Definition: Hdf5File.cpp:223
Calculate root mean square.
The class for real matrices.
Definition: RealMatrix.h:47
virtual void freeMemory()
Free memory.
virtual void create()
Create a HDF5 stream and allocate data for it.
size_t getCompressionLevel() const
Get compression level.
Definition: Parameters.h:127
std::string mRootObjectName
HDF5 group/dataset in the output file where to store data in.
hid_t getRootGroup() const
Get handle to the root group of the file.
Definition: Hdf5File.h:608
size_t getNt() const
Get total number of time steps.
Definition: Parameters.h:203
const IndexMatrix & sensorMask
Sensor mask to sample data.
hid_t mDataset
Handle to a HDF5 dataset.
size_t mSampledTimeStep
Time step to store (N/A for aggregated).
virtual ~IndexOutputStream()
Destructor.
const ReduceOperator mReduceOp
Reduction operator.
virtual void close()
Close stream (apply post-processing if necessary, flush data and close).
Class storing all parameters of the simulation.
Definition: Parameters.h:50
virtual void allocateMemory()
Allocate memory using proper memory alignment.
virtual void postProcess()
Apply post-processing on the buffer and flush it to the file.
virtual size_t * getData()
Get raw data out of the class (for direct kernel access).
virtual void postProcess()
Apply post-processing on the buffer and flush it to the file.
Store actual data (time series).
virtual size_t size() const
Size of the matrix.
The header file containing the parameters of the simulation.
void writeMatrixDomainType(const hid_t parentGroup, MatrixName &datasetName, const MatrixDomainType &matrixDomainType)
Write matrix data type into the dataset at a specified place in the file tree.
Definition: Hdf5File.cpp:807
void closeDataset(const hid_t dataset)
Close dataset.
Definition: Hdf5File.cpp:325
virtual void sample()
Sample data into buffer, apply reduction or flush to disk - based on a sensor mask.
void writeMatrixDataType(const hid_t parentGroup, MatrixName &datasetName, const MatrixDataType &matrixDataType)
Write matrix data type into the dataset at a specified place in the file tree.
Definition: Hdf5File.cpp:793
size_t getSamplingStartTimeIndex() const
Get start time index when sensor data collection begins.
Definition: Parameters.h:499
Class wrapping the HDF5 routines.
Definition: Hdf5File.h:490
IndexOutputStream()=delete
Default constructor not allowed.
size_t mBufferSize
Buffer size.
void writeHyperSlab(const hid_t dataset, const DimensionSizes &position, const DimensionSizes &size, const T *data)
Write a hyperslab into the dataset.
Definition: Hdf5File.cpp:335
const std::string MatrixName
Datatype for matrix names.
Definition: MatrixNames.h:39
Structure with 4D dimension sizes (3 in space and 1 in time).
The matrix is stored in floating point 32b wide format.
Hdf5File & mFile
Handle to HDF5 output file.
size_t getTimeIndex() const
Get actual simulation time step.
Definition: Parameters.h:208
const RealMatrix & mSourceMatrix
Source matrix to be sampled.
float * mStoreBuffer
Temporary buffer for store - only if Buffer Reuse = false!
ReduceOperator
How to aggregate data.
virtual float * getData()
Get raw data out of the class (for direct kernel access).
void readCompleteDataset(const hid_t parentGroup, MatrixName &datasetName, const DimensionSizes &dimensionSizes, T *data)
Read data from the dataset at a specified place in the file tree.
Definition: Hdf5File.cpp:678
static Parameters & getInstance()
Get instance of the singleton class.
Definition: Parameters.cpp:84
virtual void checkpoint()
Checkpoint the stream.
The class for 64b unsigned integers (indices). It is used for linear and cuboid corners masks to get ...
Definition: IndexMatrix.h:47
hid_t createDataset(const hid_t parentGroup, MatrixName &datasetName, const DimensionSizes &dimensionSizes, const DimensionSizes &chunkSizes, const MatrixDataType matrixDataType, const size_t compressionLevel)
Create a float HDF5 dataset at a specified place in the file tree (3D/4D).
Definition: Hdf5File.cpp:241
static constexpr size_t kChunkSize4MB
chunk size of 4MB in number of float elements.
Abstract base class for output data streams (sampled data).
The header file of the class saving data based on the index senor mask into the output HDF5 file...
The matrix is defined on real domain.
bool mBufferReuse
if true, the container reuses another matrix as scratch place, e.g. Temp_1_RS3D, Temp_2_RS3D, Temp_3_RS3D.
virtual void flushBufferToFile()
Flush the buffer to the file.