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

- Main Page
- Related Pages
- Classes
- Files

- File List
- File Members

All Classes Files Functions Variables Typedefs Enumerations Friends Pages
OutputHDF5Stream.cpp
Go to the documentation of this file.
1 /**
2 * @file OutputHDF5Stream.cpp
3 * @author Jiri Jaros \n
4 * Faculty of Information Technology\n
5 * Brno University of Technology \n
6 * jarosjir@fit.vutbr.cz
7 *
8 * @brief The implementation file of classes responsible for storing output
9 * quantities into the output HDF5 file
10 *
11 * @version kspaceFirstOrder3D 2.15
12 *
13 * @date 11 July 2012, 10:30 (created) \n
14 * 26 September 2014, 18:36 (revised)
15 *
16 * @section License
17 * This file is part of the C++ extension of the k-Wave Toolbox (http://www.k-wave.org).\n
18 * Copyright (C) 2014 Jiri Jaros and Bradley Treeby
19 *
20 * This file is part of k-Wave. k-Wave is free software: you can redistribute it
21 * and/or modify it under the terms of the GNU Lesser General Public License as
22 * published by the Free Software Foundation, either version 3 of the License,
23 * or (at your option) any later version.
24 *
25 * k-Wave is distributed in the hope that it will be useful, but
26 * WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
28 * See the GNU Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public License
31 * along with k-Wave. If not, see <http://www.gnu.org/licenses/>.
32 */
33
34
35 #include <string.h>
36 #include <cmath>
37 #include <immintrin.h>
38 #include <MatrixClasses/OutputHDF5Stream.h>
39
40 #include <Parameters/Parameters.h>
41 #include <Utils/ErrorMessages.h>
42 #include <limits>
43
44
45 using namespace std;
46
47 //----------------------------------------------------------------------------//
48 // Constants //
49 //----------------------------------------------------------------------------//
50
51
52
53 //----------------------------------------------------------------------------//
54 // Definitions //
55 //----------------------------------------------------------------------------//
56
57
58 //----------------------------------------------------------------------------//
59 // TBaseOutputHDF5Stream implementation //
60 // public methods //
61 //----------------------------------------------------------------------------//
62
63
64 /**
65 * Apply post-processing on the buffer. It supposes the elements are independent.
66 *
67 */
68 void TBaseOutputHDF5Stream::PostProcess()
69 {
70 switch (ReductionOp)
71 {
72 case roNONE :
73 {
74 // do nothing
75 break;
76 }
77
78 case roRMS :
79 {
80 const float ScalingCoeff = 1.0f / (TParameters::GetInstance()->Get_Nt() - TParameters::GetInstance()->GetStartTimeIndex());
81
82 #pragma omp parallel for if (BufferSize > MinGridpointsToSampleInParallel)
83 for (size_t i = 0; i < BufferSize; i++)
84 {
85 StoreBuffer[i] = sqrt(StoreBuffer[i] * ScalingCoeff);
86 }
87 break;
88 }
89
90 case roMAX :
91 {
92 // do nothing
93 break;
94 }
95
96 case roMIN :
97 {
98 // do nothing
99 break;
100 }
101 }// switch
102
103 }// end of ApplyPostProcessing
104 //------------------------------------------------------------------------------
105
106
107
108 //----------------------------------------------------------------------------//
109 // TBaseOutputHDF5Stream implementation //
110 // public methods //
111 //----------------------------------------------------------------------------//
112
113
114 /**
115 * Allocate memory using a proper memory alignment.
116 * @warning This can routine is not used in the base class (should be used in
117 * derived ones).
118 */
119 void TBaseOutputHDF5Stream::AllocateMemory()
120 {
121 StoreBuffer = (float *) _mm_malloc(BufferSize * sizeof (float), DATA_ALIGNMENT);
122
123 if (!StoreBuffer)
124 {
125 fprintf(stderr, Matrix_ERR_FMT_NotEnoughMemory, "TBaseOutputHDF5Stream");
126 throw bad_alloc();
127 }
128
129 // we need different initialization for different reduction ops
130 switch (ReductionOp)
131 {
132 case roNONE :
133 {
134 // zero the matrix
135 #pragma omp parallel for if (BufferSize > MinGridpointsToSampleInParallel)
136 for (size_t i = 0; i < BufferSize; i++)
137 {
138 StoreBuffer[i] = 0.0f;
139 }
140 break;
141 }
142
143 case roRMS :
144 {
145 // zero the matrix
146 #pragma omp parallel for if (BufferSize > MinGridpointsToSampleInParallel)
147 for (size_t i = 0; i < BufferSize; i++)
148 {
149 StoreBuffer[i] = 0.0f;
150 }
151 break;
152 }
153
154 case roMAX :
155 {
156 // set the values to the highest negative float value
157 #pragma omp parallel for if (BufferSize > MinGridpointsToSampleInParallel)
158 for (size_t i = 0; i < BufferSize; i++)
159 {
160 StoreBuffer[i] = -1 * std::numeric_limits<float>::max();
161 }
162 break;
163 }
164
165 case roMIN :
166 {
167 // set the values to the highest float value
168 #pragma omp parallel for if (BufferSize > MinGridpointsToSampleInParallel)
169 for (size_t i = 0; i < BufferSize; i++)
170 {
171 StoreBuffer[i] = std::numeric_limits<float>::max();
172 }
173 break;
174 }
175 }// switch
176 }// end of AllocateMemory
177 //------------------------------------------------------------------------------
178
179 /**
180 * Free memory.
181 * @warning This can routine is not used in the base class (should be used in
182 * derived ones).
183 */
184 void TBaseOutputHDF5Stream::FreeMemory()
185 {
186 if (StoreBuffer)
187 {
188 _mm_free(StoreBuffer);
189 StoreBuffer = NULL;
190 }
191 }// end of FreeMemory
192 //------------------------------------------------------------------------------
193
194
195 //----------------------------------------------------------------------------//
196 // TIndexOutputHDF5Stream implementation //
197 // public methods //
198 //----------------------------------------------------------------------------//
199
200 /**
201 * Constructor - links the HDF5 dataset, source (sampled matrix), Sensor mask
202 * and the reduction operator together. The constructor DOES NOT allocate memory
203 * because the size of the sensor mask is not known at the time the instance of
204 * the class is being created.
205 *
206 * @param [in] HDF5_File - Handle to the HDF5 (output) file
207 * @param [in] HDF5_ObjectName - The dataset's name (index based sensor data
208 * is store in a single dataset)
209 * @param [in] SourceMatrix - The source matrix (only real matrices are
210 * supported)
211 * @param [in] SensorMask - Index based sensor mask
212 * @param [in] ReductionOp - Reduction operator
213 * @param [in] BufferToReuse - An external buffer can be used to line up
214 * the grid points
215 */
216 TIndexOutputHDF5Stream::TIndexOutputHDF5Stream(THDF5_File & HDF5_File,
217 const char * HDF5_ObjectName,
218 const TRealMatrix & SourceMatrix,
219 const TIndexMatrix & SensorMask,
220 const TReductionOperator ReductionOp,
221 float * BufferToReuse)
222 : TBaseOutputHDF5Stream(HDF5_File, HDF5_ObjectName, SourceMatrix, ReductionOp, BufferToReuse),
223 SensorMask(SensorMask),
224 HDF5_DatasetId(H5I_BADID),
225 SampledTimeStep(0)
226 {
227
228 }// end of TIndexOutputHDF5Stream
229 //------------------------------------------------------------------------------
230
231
232 /**
233 * Destructor.
234 * if the file is still opened, it applies the post processing and flush the data.
235 * Then, the object memory is freed and the object destroyed.
236 */
237 TIndexOutputHDF5Stream::~TIndexOutputHDF5Stream()
238 {
239 Close();
240 // free memory only if it was allocated
241 if (!BufferReuse) FreeMemory();
242 }// end of Destructor
243 //------------------------------------------------------------------------------
244
245
246
247 /**
248 * Create a HDF5 stream, create a dataset, and allocate data for it.
249 */
250 void TIndexOutputHDF5Stream::Create()
251 {
252 size_t NumberOfSampledElementsPerStep = SensorMask.GetTotalElementCount();
253
254 TParameters * Params = TParameters::GetInstance();
255
256 // Derive dataset dimension sizes
257 TDimensionSizes DatasetSize(NumberOfSampledElementsPerStep,
258 (ReductionOp == roNONE) ? Params->Get_Nt() - Params->GetStartTimeIndex() : 1,
259 1);
260
261 // Set HDF5 chunk size
262 TDimensionSizes ChunkSize(NumberOfSampledElementsPerStep, 1, 1);
263 // for chunks bigger than 32 MB
264 if (NumberOfSampledElementsPerStep > (ChunkSize_4MB * 8))
265 {
266 ChunkSize.X = ChunkSize_4MB; // set chunk size to MB
267 }
268
269 // Create a dataset under the root group
270 HDF5_DatasetId = HDF5_File.CreateFloatDataset(HDF5_File.GetRootGroup(),
271 HDF5_RootObjectName,
272 DatasetSize,
273 ChunkSize,
274 Params->GetCompressionLevel());
275
276 // Write dataset parameters
277 HDF5_File.WriteMatrixDomainType(HDF5_File.GetRootGroup(),
278 HDF5_RootObjectName,
279 THDF5_File::hdf5_mdt_real);
280 HDF5_File.WriteMatrixDataType (HDF5_File.GetRootGroup(),
281 HDF5_RootObjectName,
282 THDF5_File::hdf5_mdt_float);
283
284
285 // Sampled time step
286 SampledTimeStep = 0;
287
288 // Set buffer size
289 BufferSize = NumberOfSampledElementsPerStep;
290
291 // Allocate memory if needed
292 if (!BufferReuse) AllocateMemory();
293 }// end of Create
294 //------------------------------------------------------------------------------
295
296 /**
297 * Reopen the output stream after restart.
298 */
299 void TIndexOutputHDF5Stream::Reopen()
300 {
301 // Get parameters
302 TParameters * Params = TParameters::GetInstance();
303
304 // Set buffer size
305 BufferSize = SensorMask.GetTotalElementCount();
306
307 // Allocate memory if needed
308 if (!BufferReuse) AllocateMemory();
309
310 // Reopen the dataset
311 HDF5_DatasetId = HDF5_File.OpenDataset(HDF5_File.GetRootGroup(),
312 HDF5_RootObjectName);
313
314
315 if (ReductionOp == roNONE)
316 { // raw time series - just seek to the right place in the dataset
317 SampledTimeStep = ((Params->Get_t_index() - Params->GetStartTimeIndex()) < 0) ?
318 0 : (Params->Get_t_index() - Params->GetStartTimeIndex());
319
320 }
321 else
322 { // aggregated quantities - reload data
323 SampledTimeStep = 0;
324
325 // Since there is only a single timestep in the dataset, I can read the whole dataset
326 HDF5_File.ReadCompleteDataset(HDF5_File.GetRootGroup(),
327 HDF5_RootObjectName,
328 TDimensionSizes(BufferSize, 1, 1),
329 StoreBuffer);
330 }
331 }// end of Reopen
332 //------------------------------------------------------------------------------
333
334
335 /**
336 * Sample grid points, line them up in the buffer an flush to the disk unless a
337 * reduction operator is applied.
338 */
339 void TIndexOutputHDF5Stream::Sample()
340 {
341 const float * SourceData = SourceMatrix.GetRawData();
342 const size_t * SensorData = SensorMask.GetRawData();
343
344 switch (ReductionOp)
345 {
346 case roNONE :
347 {
348 #pragma omp parallel for if (BufferSize > MinGridpointsToSampleInParallel)
349 for (size_t i = 0; i < BufferSize; i++)
350 {
351 StoreBuffer[i] = SourceData[SensorData[i]];
352 }
353 // only raw time series are flushed down to the disk every time step
354 FlushBufferToFile();
355 /* - for future use when offloading the sampling work to HDF5 - now it seem to be slower
356 HDF5_File.WriteSensorbyMaskToHyperSlab(HDF5_DatasetId,
357 Position, // position in the dataset
358 BufferSize, // number of elements sampled
359 SensorMask.GetRawData(), // Sensor
360 SourceMatrix.GetDimensionSizes(), // Matrix dims
361 SourceMatrix.GetRawData());
362 Position.Y++;
363 */
364 break;
365 }// case roNONE
366
367 case roRMS :
368 {
369 #pragma omp parallel for if (BufferSize > MinGridpointsToSampleInParallel)
370 for (size_t i = 0; i < BufferSize; i++)
371 {
372 StoreBuffer[i] += (SourceData[SensorData[i]] * SourceData[SensorData[i]]);
373 }
374 break;
375 }// case roRMS
376
377 case roMAX :
378 {
379 #pragma omp parallel for if (BufferSize > MinGridpointsToSampleInParallel)
380 for (size_t i = 0; i < BufferSize; i++)
381 {
382 if (StoreBuffer[i] < SourceData[SensorData[i]])
383 StoreBuffer[i] = SourceData[SensorData[i]];
384 }
385 break;
386 }// case roMAX
387
388 case roMIN :
389 {
390 #pragma omp parallel for if (BufferSize > MinGridpointsToSampleInParallel)
391 for (size_t i = 0; i < BufferSize; i++)
392 {
393 if (StoreBuffer[i] > SourceData[SensorData[i]])
394 StoreBuffer[i] = SourceData[SensorData[i]];
395 }
396 break;
397 } //case roMIN
398 }// switch
399 }// end of Sample
400 //------------------------------------------------------------------------------
401
402 /**
403 * Apply post-processing on the buffer and flush it to the file.
404 */
405 void TIndexOutputHDF5Stream::PostProcess()
406 {
407 // run inherited method
408 TBaseOutputHDF5Stream::PostProcess();
409 // When no reduction operator is applied, the data is flushed after every time step
410 if (ReductionOp != roNONE) FlushBufferToFile();
411 }// end of PostProcessing
412 //------------------------------------------------------------------------------
413
414
415 /**
416 * Checkpoint the stream and close.
417 */
418 void TIndexOutputHDF5Stream::Checkpoint()
419 {
420 // raw data has already been flushed, others has to be fushed here
421 if (ReductionOp != roNONE) FlushBufferToFile();
422
423 }// end of Checkpoint
424 //------------------------------------------------------------------------------
425
426 /**
427 * Close stream (apply post-processing if necessary, flush data and close).
428 */
429 void TIndexOutputHDF5Stream::Close()
430 {
431 // the dataset is still opened
432 if (HDF5_DatasetId != H5I_BADID)
433 {
434 HDF5_File.CloseDataset(HDF5_DatasetId);
435 }
436
437 HDF5_DatasetId = H5I_BADID;
438 }// end of Close
439 //------------------------------------------------------------------------------
440
441 //----------------------------------------------------------------------------//
442 // TIndexOutputHDF5Stream implementation //
443 // protected methods //
444 //----------------------------------------------------------------------------//
445
446
447 /**
448 * Flush the buffer down to the file at the actual position.
449 */
450 void TIndexOutputHDF5Stream::FlushBufferToFile()
451 {
452 HDF5_File.WriteHyperSlab(HDF5_DatasetId,
453 TDimensionSizes(0,SampledTimeStep,0),
454 TDimensionSizes(BufferSize,1,1),
455 StoreBuffer);
456 SampledTimeStep++;
457 }// end of FlushToFile
458 //------------------------------------------------------------------------------
459
460
461
462
463
464
465 //----------------------------------------------------------------------------//
466 // TCuboidOutputHDF5Stream implementation //
467 // public methods //
468 //----------------------------------------------------------------------------//
469
470
471 /**
472 * Constructor - links the HDF5 dataset, SourceMatrix, and SensorMask together.
473 * @param [in] HDF5_File - HDF5 file to write the output to
474 * @param [in] HDF5_GroupName - The name of the HDF5 group. This group contains datasets for particular cuboids
475 * @param [in] SourceMatrix - Source matrix to be sampled
476 * @param [in] SensorMask - Sensor mask with the cuboid coordinates
477 * @param [in] ReductionOp - Reduction operator
478 * @param [in] BufferToReuse - If there is a memory space to be reused, provide a pointer
479 */
480 TCuboidOutputHDF5Stream::TCuboidOutputHDF5Stream(THDF5_File & HDF5_File,
481 const char * HDF5_GroupName,
482 const TRealMatrix & SourceMatrix,
483 const TIndexMatrix & SensorMask,
484 const TReductionOperator ReductionOp,
485 float * BufferToReuse)
486 : TBaseOutputHDF5Stream(HDF5_File, HDF5_GroupName, SourceMatrix, ReductionOp, BufferToReuse),
487 SensorMask(SensorMask),
488 HDF5_GroupId(H5I_BADID),
489 SampledTimeStep(0)
490 {
491
492 }// end of TCubodidOutputHDF5Stream
493 //------------------------------------------------------------------------------
494
495
496 /**
497 * Destructor.
498 * if the file is still opened, it applies the post processing and flush the data.
499 * Then, the object memory is freed and the object destroyed.
500 */
501 TCuboidOutputHDF5Stream::~TCuboidOutputHDF5Stream()
502 {
503 Close();
504
505 // free memory only if it was allocated
506 if (!BufferReuse) FreeMemory();
507 }// end ~TCubodidOutputHDF5Stream
508 //------------------------------------------------------------------------------
509
510
511 /**
512 * Create a HDF5 stream and allocate data for it. It also creates a HDF5 group
513 * with particular datasets (one per cuboid).
514 */
515 void TCuboidOutputHDF5Stream::Create()
516 {
517 // Create the HDF5 group and open it
518 HDF5_GroupId = HDF5_File.CreateGroup(HDF5_File.GetRootGroup(), HDF5_RootObjectName);
519
520 // Create all datasets (sizes, chunks, and attributes)
521 size_t NumberOfCuboids = SensorMask.GetDimensionSizes().Y;
522 CuboidsInfo.reserve(NumberOfCuboids);
523 size_t ActualPositionInBuffer = 0;
524
525 for (size_t CuboidIndex = 0; CuboidIndex < NumberOfCuboids; CuboidIndex++)
526 {
527 TCuboidInfo CuboidInfo;
528
529 CuboidInfo.HDF5_CuboidId = CreateCuboidDataset(CuboidIndex);
530 CuboidInfo.StartingPossitionInBuffer = ActualPositionInBuffer;
531 CuboidsInfo.push_back(CuboidInfo);
532
533 ActualPositionInBuffer += (SensorMask.GetBottomRightCorner(CuboidIndex) - SensorMask.GetTopLeftCorner(CuboidIndex)).GetElementCount();
534 }
535
536 //we're at the beginning
537 SampledTimeStep = 0;
538
539 // Create the memory buffer if necessary and set starting address
540 BufferSize = SensorMask.GetTotalNumberOfElementsInAllCuboids();
541
542 // Allocate memory if needed
543 if (!BufferReuse) AllocateMemory();
544 }// end of Create
545 //------------------------------------------------------------------------------
546
547
548 /**
549 * Reopen the output stream after restart and reload data.
550 */
551 void TCuboidOutputHDF5Stream::Reopen()
552 {
553 // Get parameters
554 TParameters * Params = TParameters::GetInstance();
555
556 SampledTimeStep = 0;
557 if (ReductionOp == roNONE) // set correct sampled timestep for raw data series
558 {
559 SampledTimeStep = ((Params->Get_t_index() - Params->GetStartTimeIndex()) < 0) ?
560 0 : (Params->Get_t_index() - Params->GetStartTimeIndex());
561 }
562
563 // Create the memory buffer if necessary and set starting address
564 BufferSize = SensorMask.GetTotalNumberOfElementsInAllCuboids();
565
566 // Allocate memory if needed
567 if (!BufferReuse) AllocateMemory();
568
569
570 // Open all datasets (sizes, chunks, and attributes)
571 size_t NumberOfCuboids = SensorMask.GetDimensionSizes().Y;
572 CuboidsInfo.reserve(NumberOfCuboids);
573 size_t ActualPositionInBuffer = 0;
574
575 // Open the HDF5 group
576 HDF5_GroupId = HDF5_File.OpenGroup(HDF5_File.GetRootGroup(), HDF5_RootObjectName);
577
578 for (size_t CuboidIndex = 0; CuboidIndex < NumberOfCuboids; CuboidIndex++)
579 {
580 TCuboidInfo CuboidInfo;
581
582 // @todo: Can be done easily with std::to_string and c++0x or c++-11
583 char HDF5_DatasetName[32] = "";
584 // Indexed from 1
585 sprintf(HDF5_DatasetName, "%ld",CuboidIndex + 1);
586
587 // open the dataset
588 CuboidInfo.HDF5_CuboidId = HDF5_File.OpenDataset(HDF5_GroupId,
589 HDF5_DatasetName);
590 CuboidInfo.StartingPossitionInBuffer = ActualPositionInBuffer;
591 CuboidsInfo.push_back(CuboidInfo);
592
593 if (ReductionOp != roNONE)
594 { // Reload data
595 TDimensionSizes CuboidSize((SensorMask.GetBottomRightCorner(CuboidIndex) - SensorMask.GetTopLeftCorner(CuboidIndex)).X,
596 (SensorMask.GetBottomRightCorner(CuboidIndex) - SensorMask.GetTopLeftCorner(CuboidIndex)).Y,
597 (SensorMask.GetBottomRightCorner(CuboidIndex) - SensorMask.GetTopLeftCorner(CuboidIndex)).Z);
598
599 HDF5_File.ReadCompleteDataset(HDF5_GroupId,
600 HDF5_DatasetName,
601 CuboidSize,
602 StoreBuffer + ActualPositionInBuffer);
603 }
604 // move the pointer for the next cuboid beginning
605 ActualPositionInBuffer += (SensorMask.GetBottomRightCorner(CuboidIndex) -
606 SensorMask.GetTopLeftCorner(CuboidIndex)).GetElementCount();
607 }
608 }// end of Reopen
609 //------------------------------------------------------------------------------
610
611 /**
612 * Sample data into buffer and apply reduction, or flush to disk - based on a sensor mask.
613 */
614 void TCuboidOutputHDF5Stream::Sample()
615 {
616 const size_t XY_Size = SourceMatrix.GetDimensionSizes().Y * SourceMatrix.GetDimensionSizes().X;
617 const size_t X_Size = SourceMatrix.GetDimensionSizes().X;
618
619 const float * SourceData = SourceMatrix.GetRawData();
620
621 switch (ReductionOp)
622 {
623 case roNONE :
624 {
625 /* We use here direct HDF5 offload using MEMSPACE - seems to be faster for bigger datasets*/
626 TDimensionSizes DatasetPosition(0,0,0,0); //4D position in the dataset
627 TDimensionSizes CuboidSize(0,0,0,0); // Size of the cuboid
628
629 DatasetPosition.T = SampledTimeStep;
630 const float * MatrixData = SourceMatrix.GetRawData();
631
632 // iterate over all cuboid to be sampled
633 for (size_t CuboidIndex = 0; CuboidIndex < CuboidsInfo.size(); CuboidIndex++)
634 {
635 CuboidSize = SensorMask.GetBottomRightCorner(CuboidIndex) - SensorMask.GetTopLeftCorner(CuboidIndex);
636 CuboidSize.T = 1;
637
638 HDF5_File.WriteCuboidToHyperSlab(CuboidsInfo[CuboidIndex].HDF5_CuboidId,
639 DatasetPosition,
640 SensorMask.GetTopLeftCorner(CuboidIndex), // position in the SourceMatrix
641 CuboidSize,
642 SourceMatrix.GetDimensionSizes(),
643 MatrixData);
644 }
645 SampledTimeStep++; // Move forward in time
646
647 break;
648
649 /* At the time being, this version using manual data lining up seems to be slower, and is not used
650 size_t BufferStart = 0;
651
652 for (size_t CuboidIdx = 0; CuboidIdx < SensorMask.GetDimensionSizes().Y; CuboidIdx++)
653 {
654 const TDimensionSizes TopLeftCorner = SensorMask.GetTopLeftCorner(CuboidIdx);
655 const TDimensionSizes BottomRightCorner = SensorMask.GetBottomRightCorner(CuboidIdx);
656
657 size_t cuboid_XY_plane_size = ( BottomRightCorner.Y - TopLeftCorner.Y) * ( BottomRightCorner.X - TopLeftCorner.X);
658 size_t cuboid_X_plane_size = ( BottomRightCorner.X - TopLeftCorner.X);
659
660 #pragma omp parallel for collapse(3)
661 for (size_t z = TopLeftCorner.Z; z <= BottomRightCorner.Z; z++)
662 for (size_t y = TopLeftCorner.Y; y <= BottomRightCorner.Y; y++)
663 for (size_t x = TopLeftCorner.X; x <= BottomRightCorner.X; x++)
664 {
665 StoreBuffer[BufferStart +
666 (z - TopLeftCorner.Z) * cuboid_XY_plane_size +
667 (y - TopLeftCorner.Y) * cuboid_X_plane_size +
668 (x - TopLeftCorner.X) ]
669
670 = SourceMatrix[z * XY_Size + y * X_Size + x];
671 }
672 BufferStart += (BottomRightCorner - TopLeftCorner).GetElementCount();
673 }
674 FlushBufferToFile();
675 break;
676 */
677 }// case roNONE
678
679 case roRMS :
680 {
681 size_t CuboidInBufferStart = 0;
682
683 // Parallelise within the cuboid - Since a typical number of cuboids is 1, than we have to paralelise inside
684 for (size_t CuboidIdx = 0; CuboidIdx < SensorMask.GetDimensionSizes().Y; CuboidIdx++)
685 {
686 const TDimensionSizes TopLeftCorner = SensorMask.GetTopLeftCorner(CuboidIdx);
687 const TDimensionSizes BottomRightCorner = SensorMask.GetBottomRightCorner(CuboidIdx);
688
689 size_t cuboid_XY_plane_size = (BottomRightCorner.Y - TopLeftCorner.Y + 1) *
690 (BottomRightCorner.X - TopLeftCorner.X + 1);
691 size_t cuboid_X_plane_size = (BottomRightCorner.X - TopLeftCorner.X + 1);
692
693 #pragma omp parallel for collapse(3) \
694 if ((BottomRightCorner - TopLeftCorner).GetElementCount() > MinGridpointsToSampleInParallel)
695 for (size_t z = TopLeftCorner.Z; z <= BottomRightCorner.Z; z++)
696 for (size_t y = TopLeftCorner.Y; y <= BottomRightCorner.Y; y++)
697 for (size_t x = TopLeftCorner.X; x <= BottomRightCorner.X; x++)
698 {
699 const size_t StoreBufferIndex = CuboidInBufferStart +
700 (z - TopLeftCorner.Z) * cuboid_XY_plane_size +
701 (y - TopLeftCorner.Y) * cuboid_X_plane_size +
702 (x - TopLeftCorner.X);
703
704 const size_t SourceIndex = z * XY_Size + y * X_Size + x;
705
706 // aggregating the sum over timesteps
707 StoreBuffer[StoreBufferIndex] += (SourceData[SourceIndex] * SourceData[SourceIndex]);
708 }
709
710 CuboidInBufferStart += (BottomRightCorner - TopLeftCorner).GetElementCount();
711 }
712
713 break;
714 }// case roRMS
715
716 case roMAX :
717 {
718 size_t CuboidInBufferStart = 0;
719
720 // Parallelise within the cuboid - Since a typical number of cuboids is 1, than we have to paralelise inside.
721 for (size_t CuboidIdx = 0; CuboidIdx < SensorMask.GetDimensionSizes().Y; CuboidIdx++)
722 {
723 const TDimensionSizes TopLeftCorner = SensorMask.GetTopLeftCorner(CuboidIdx);
724 const TDimensionSizes BottomRightCorner = SensorMask.GetBottomRightCorner(CuboidIdx);
725
726 size_t cuboid_XY_plane_size = (BottomRightCorner.Y - TopLeftCorner.Y + 1) *
727 (BottomRightCorner.X - TopLeftCorner.X + 1);
728 size_t cuboid_X_plane_size = (BottomRightCorner.X - TopLeftCorner.X + 1);
729
730 #pragma omp parallel for collapse(3) \
731 if ((BottomRightCorner - TopLeftCorner).GetElementCount() > MinGridpointsToSampleInParallel)
732 for (size_t z = TopLeftCorner.Z; z <= BottomRightCorner.Z; z++)
733 for (size_t y = TopLeftCorner.Y; y <= BottomRightCorner.Y; y++)
734 for (size_t x = TopLeftCorner.X; x <= BottomRightCorner.X; x++)
735 {
736 const size_t StoreBufferIndex = CuboidInBufferStart +
737 (z - TopLeftCorner.Z) * cuboid_XY_plane_size +
738 (y - TopLeftCorner.Y) * cuboid_X_plane_size +
739 (x - TopLeftCorner.X);
740
741 const size_t SourceIndex = z * XY_Size + y * X_Size + x;
742
743 // finding max
744 if (StoreBuffer[StoreBufferIndex] < SourceData[SourceIndex])
745 {
746 StoreBuffer[StoreBufferIndex] = SourceData[SourceIndex];
747 }
748 }
749 CuboidInBufferStart += (BottomRightCorner - TopLeftCorner).GetElementCount();
750 }
751 break;
752 }// case roMAX
753
754 case roMIN :
755 {
756 size_t CuboidInBufferStart = 0;
757
758 // Parallelise within the cuboid - Since a typical number of cuboids is 1, than we have to paralelise inside.
759 for (size_t CuboidIdx = 0; CuboidIdx < SensorMask.GetDimensionSizes().Y; CuboidIdx++)
760 {
761 const TDimensionSizes TopLeftCorner = SensorMask.GetTopLeftCorner(CuboidIdx);
762 const TDimensionSizes BottomRightCorner = SensorMask.GetBottomRightCorner(CuboidIdx);
763
764 size_t cuboid_XY_plane_size = (BottomRightCorner.Y - TopLeftCorner.Y + 1) *
765 (BottomRightCorner.X - TopLeftCorner.X + 1);
766 size_t cuboid_X_plane_size = (BottomRightCorner.X - TopLeftCorner.X + 1);
767
768 #pragma omp parallel for collapse(3) \
769 if ((BottomRightCorner - TopLeftCorner).GetElementCount() > MinGridpointsToSampleInParallel)
770 for (size_t z = TopLeftCorner.Z; z <= BottomRightCorner.Z; z++)
771 for (size_t y = TopLeftCorner.Y; y <= BottomRightCorner.Y; y++)
772 for (size_t x = TopLeftCorner.X; x <= BottomRightCorner.X; x++)
773 {
774 const size_t StoreBufferIndex = CuboidInBufferStart +
775 (z - TopLeftCorner.Z) * cuboid_XY_plane_size +
776 (y - TopLeftCorner.Y) * cuboid_X_plane_size +
777 (x - TopLeftCorner.X);
778 const size_t SourceIndex = z * XY_Size + y * X_Size + x;
779
780 // finding min
781 if (StoreBuffer[StoreBufferIndex] > SourceData[SourceIndex])
782 {
783 StoreBuffer[StoreBufferIndex] = SourceData[SourceIndex];
784 }
785 }
786 CuboidInBufferStart += (BottomRightCorner - TopLeftCorner).GetElementCount();
787 }
788
789 break;
790 }// case roMIN
791 }// switch
792 }// end of Sample
793 //------------------------------------------------------------------------------
794
795
796 /**
797 * Apply post-processing on the buffer and flush it to the file.
798 */
799 void TCuboidOutputHDF5Stream::PostProcess()
800 {
801 // run inherited method
802 TBaseOutputHDF5Stream::PostProcess();
803 // When no reduction operator is applied, the data is flushed after every time step
804 if (ReductionOp != roNONE) FlushBufferToFile();
805 }// end of PostProcessing
806 //------------------------------------------------------------------------------
807
808 /**
809 * Checkpoint the stream.
810 */
811 void TCuboidOutputHDF5Stream::Checkpoint()
812 {
813 // raw data has already been flushed, others has to be fushed here
814 if (ReductionOp != roNONE) FlushBufferToFile();
815 }// end of Checkpoint
816 //------------------------------------------------------------------------------
817
818
819 /**
820 * Close stream (apply post-processing if necessary, flush data, close datasets
821 * and the group).
822 */
823 void TCuboidOutputHDF5Stream::Close()
824 {
825 // the group is still open
826 if (HDF5_GroupId != H5I_BADID)
827 {
828 // Close all datasets and the group
829 for (size_t CuboidIndex = 0; CuboidIndex < CuboidsInfo.size(); CuboidIndex++)
830 {
831 HDF5_File.CloseDataset(CuboidsInfo[CuboidIndex].HDF5_CuboidId);
832 }
833 CuboidsInfo.clear();
834
835 HDF5_File.CloseGroup(HDF5_GroupId);
836 HDF5_GroupId = H5I_BADID;
837 }// if opened
838 }// end of Close
839 //------------------------------------------------------------------------------
840
841
842
843 //----------------------------------------------------------------------------//
844 // TIndexOutputHDF5Stream implementation //
845 // protected methods //
846 //----------------------------------------------------------------------------//
847
848 /**
849 * Create a new dataset for a given cuboid specified by index (order).
850 * @param [in] Index - Index of the cuboid in the sensor mask
851 * @return HDF5 handle to the dataset.
852 */
853 hid_t TCuboidOutputHDF5Stream::CreateCuboidDataset(const size_t Index)
854 {
855 TParameters * Params = TParameters::GetInstance();
856
857 // if time series then Number of steps else 1
858 size_t NumberOfSampledTimeSteps = (ReductionOp == roNONE)
859 ? Params->Get_Nt() - Params->GetStartTimeIndex()
860 : 0; // will be a 3D dataset
861 // Set cuboid dimensions
862 TDimensionSizes CuboidSize((SensorMask.GetBottomRightCorner(Index) - SensorMask.GetTopLeftCorner(Index)).X,
863 (SensorMask.GetBottomRightCorner(Index) - SensorMask.GetTopLeftCorner(Index)).Y,
864 (SensorMask.GetBottomRightCorner(Index) - SensorMask.GetTopLeftCorner(Index)).Z,
865 NumberOfSampledTimeSteps
866 );
867
868 // Set chunk size
869 // If the size of the cuboid is bigger than 32 MB per timestep, set the chunk to approx 4MB
870 size_t NumberOfSlabs = 1; //at least one slab
871 TDimensionSizes CuboidChunkSize(CuboidSize.X, CuboidSize.Y, CuboidSize.Z, (ReductionOp == roNONE) ? 1 : 0);
872
873 if (CuboidChunkSize.GetElementCount() > (ChunkSize_4MB * 8))
874 {
875 while (NumberOfSlabs * CuboidSize.X * CuboidSize.Y < ChunkSize_4MB) NumberOfSlabs++;
876 CuboidChunkSize.Z = NumberOfSlabs;
877 }
878
879 // @todo: Can be done easily with std::to_string and c++0x or c++-11
880 char HDF5_DatasetName[32] = "";
881 // Indexed from 1
882 sprintf(HDF5_DatasetName, "%ld",Index+1);
883 hid_t HDF5_DatasetId = HDF5_File.CreateFloatDataset(HDF5_GroupId,
884 HDF5_DatasetName,
885 CuboidSize,
886 CuboidChunkSize,
887 Params->GetCompressionLevel()
888 );
889
890 // Write dataset parameters
891 HDF5_File.WriteMatrixDomainType(HDF5_GroupId,
892 HDF5_DatasetName,
893 THDF5_File::hdf5_mdt_real);
894 HDF5_File.WriteMatrixDataType (HDF5_GroupId,
895 HDF5_DatasetName,
896 THDF5_File::hdf5_mdt_float);
897
898 return HDF5_DatasetId;
899 }//end of CreateCuboidDatasets
900 //------------------------------------------------------------------------------
901
902
903
904 /**
905 * Flush the buffer to the file (to multiple datasets if necessary).
906 */
907 void TCuboidOutputHDF5Stream::FlushBufferToFile()
908 {
909 TDimensionSizes Position (0,0,0,0);
910 TDimensionSizes BlockSize(0,0,0,0);
911
912 if (ReductionOp == roNONE) Position.T = SampledTimeStep;
913
914 for (size_t CuboidIndex = 0; CuboidIndex < CuboidsInfo.size(); CuboidIndex++)
915 {
916
917 BlockSize = SensorMask.GetBottomRightCorner(CuboidIndex) - SensorMask.GetTopLeftCorner(CuboidIndex);
918 BlockSize.T = 1;
919
920 HDF5_File.WriteHyperSlab(CuboidsInfo[CuboidIndex].HDF5_CuboidId,
921 Position,
922 BlockSize,
923 StoreBuffer + CuboidsInfo[CuboidIndex].StartingPossitionInBuffer
924 );
925
926 }
927
928 SampledTimeStep++;
929 }// end of FlushBufferToFile
930 //------------------------------------------------------------------------------
931
932
933
934 //----------------------------------------------------------------------------//
935 // TWholeDomainOutputHDF5Stream implementation //
936 // public methods //
937 //----------------------------------------------------------------------------//
938
939 /**
940 * Constructor - links the HDF5 dataset and SourceMatrix.
941 * @param [in] HDF5_File - HDF5 file to write the output to
942 * @param [in] HDF5_DatasetName - The name of the HDF5 group. This group contains datasets for particular cuboids
943 * @param [in] SourceMatrix - Source matrix to be sampled
944 * @param [in] ReductionOp - Reduction operator
945 * @param [in] BufferToReuse - If there is a memory space to be reused, provide a pointer
946 */
947 TWholeDomainOutputHDF5Stream::TWholeDomainOutputHDF5Stream(THDF5_File & HDF5_File,
948 const char * HDF5_DatasetName,
949 const TRealMatrix & SourceMatrix,
950 const TReductionOperator ReductionOp,
951 float * BufferToReuse)
952 : TBaseOutputHDF5Stream(HDF5_File, HDF5_DatasetName, SourceMatrix, ReductionOp, BufferToReuse),
953 HDF5_DatasetId(H5I_BADID),
954 SampledTimeStep(0)
955 {
956
957 }// end of TWholeDomainOutputHDF5Stream
958 //------------------------------------------------------------------------------
959
960 /**
961 * Destructor.
962 * if the file is still opened, it applies the post processing and flush the data.
963 * Then, the object memory is freed and the object destroyed.
964 */
965 TWholeDomainOutputHDF5Stream::~TWholeDomainOutputHDF5Stream()
966 {
967 Close();
968 // free memory only if it was allocated
969 if (!BufferReuse) FreeMemory();
970 }// end of Destructor
971 //------------------------------------------------------------------------------
972
973 /**
974 * Create a HDF5 stream for the whole domain and allocate data for it.
975 */
976 void TWholeDomainOutputHDF5Stream::Create()
977 {
978 TDimensionSizes ChunkSize(SourceMatrix.GetDimensionSizes().X, SourceMatrix.GetDimensionSizes().Y, 1);
979
980 // Create a dataset under the root group
981 HDF5_DatasetId = HDF5_File.CreateFloatDataset(HDF5_File.GetRootGroup(),
982 HDF5_RootObjectName,
983 SourceMatrix.GetDimensionSizes(),
984 ChunkSize,
985 TParameters::GetInstance()->GetCompressionLevel());
986
987 // Write dataset parameters
988 HDF5_File.WriteMatrixDomainType(HDF5_File.GetRootGroup(),
989 HDF5_RootObjectName,
990 THDF5_File::hdf5_mdt_real);
991 HDF5_File.WriteMatrixDataType (HDF5_File.GetRootGroup(),
992 HDF5_RootObjectName,
993 THDF5_File::hdf5_mdt_float);
994
995 // Set buffer size
996 BufferSize = SourceMatrix.GetTotalElementCount();
997
998 // Allocate memory if needed
999 if (!BufferReuse) AllocateMemory();
1000 }//end of Create
1001 //------------------------------------------------------------------------------
1002
1003
1004 /**
1005 * Reopen the output stream after restart and reload data.
1006 */
1007 void TWholeDomainOutputHDF5Stream::Reopen()
1008 {
1009 TParameters * Params = TParameters::GetInstance();
1010
1011 // Set buffer size
1012 BufferSize = SourceMatrix.GetTotalElementCount();
1013
1014 // Allocate memory if needed
1015 if (!BufferReuse) AllocateMemory();
1016
1017 // Open the dataset under the root group
1018 HDF5_DatasetId = HDF5_File.OpenDataset(HDF5_File.GetRootGroup(),
1019 HDF5_RootObjectName);
1020
1021 SampledTimeStep = 0;
1022 if (ReductionOp == roNONE)
1023 { // seek in the dataset
1024 SampledTimeStep = ((Params->Get_t_index() - Params->GetStartTimeIndex()) < 0) ?
1025 0 : (Params->Get_t_index() - Params->GetStartTimeIndex());
1026 }
1027 else
1028 { // reload data
1029 HDF5_File.ReadCompleteDataset(HDF5_File.GetRootGroup(),
1030 HDF5_RootObjectName,
1031 SourceMatrix.GetDimensionSizes(),
1032 StoreBuffer);
1033 }
1034 }// end of Reopen
1035 //------------------------------------------------------------------------------
1036
1037
1038 /**
1039 * Sample all grid points, line them up in the buffer an flush to the disk unless
1040 * a reduction operator is applied.
1041 */
1042 void TWholeDomainOutputHDF5Stream::Sample()
1043 {
1044 const float * SourceData = SourceMatrix.GetRawData();
1045
1046 switch (ReductionOp)
1047 {
1048 case roNONE :
1049 {
1050
1051 /* We use here direct HDF5 offload using MEMSPACE - seems to be faster for bigger datasets*/
1052 const TDimensionSizes DatasetPosition(0,0,0,SampledTimeStep); //4D position in the dataset
1053
1054 TDimensionSizes CuboidSize(SourceMatrix.GetDimensionSizes());// Size of the cuboid
1055 CuboidSize.T = 1;
1056
1057 // iterate over all cuboid to be sampled
1058 HDF5_File.WriteCuboidToHyperSlab(HDF5_DatasetId,
1059 DatasetPosition,
1060 TDimensionSizes(0,0,0,0), // position in the SourceMatrix
1061 CuboidSize,
1062 SourceMatrix.GetDimensionSizes(),
1063 SourceMatrix.GetRawData());
1064
1065 SampledTimeStep++; // Move forward in time
1066
1067 // This version is obsolete (needs one more data movement)
1068 /*
1069 #pragma omp parallel for if (BufferSize > MinGridpointsToSampleInParallel)
1070 for (size_t i = 0; i < BufferSize; i++)
1071 {
1072 StoreBuffer[i] = SourceData[i];
1073 }
1074 // only raw time series are flushed down to the disk every time step
1075 FlushBufferToFile();
1076 */
1077
1078 break;
1079 }// case roNONE
1080
1081 case roRMS :
1082 {
1083 #pragma omp parallel for if (BufferSize > MinGridpointsToSampleInParallel)
1084 for (size_t i = 0; i < BufferSize; i++)
1085 {
1086 StoreBuffer[i] += (SourceData[i] * SourceData[i]);
1087 }
1088 break;
1089 }// case roRMS
1090
1091 case roMAX :
1092 {
1093 #pragma omp parallel for if (BufferSize > MinGridpointsToSampleInParallel)
1094 for (size_t i = 0; i < BufferSize; i++)
1095 {
1096 if (StoreBuffer[i] < SourceData[i]) StoreBuffer[i] = SourceData[i];
1097 }
1098 break;
1099 }//case roMAX
1100
1101 case roMIN :
1102 {
1103 #pragma omp parallel for if (BufferSize > MinGridpointsToSampleInParallel)
1104 for (size_t i = 0; i < BufferSize; i++)
1105 {
1106 if (StoreBuffer[i] > SourceData[i]) StoreBuffer[i] = SourceData[i];
1107 }
1108 break;
1109 } //case roMIN
1110 }// switch
1111 }// end of Sample
1112 //------------------------------------------------------------------------------
1113
1114
1115 /**
1116 * Apply post-processing on the buffer and flush it to the file.
1117 */
1118 void TWholeDomainOutputHDF5Stream::PostProcess()
1119 {
1120 // run inherited method
1121 TBaseOutputHDF5Stream::PostProcess();
1122 // When no reduction operator is applied, the data is flushed after every time step
1123 if (ReductionOp != roNONE) FlushBufferToFile();
1124 }// end of PostProcessing
1125 //------------------------------------------------------------------------------
1126
1127 /**
1128 * Checkpoint the stream
1129 */
1130 void TWholeDomainOutputHDF5Stream::Checkpoint()
1131 {
1132 // raw data has already been flushed, others has to be flushed here.
1133 if (ReductionOp != roNONE) FlushBufferToFile();
1134 }// end of Checkpoint
1135 //------------------------------------------------------------------------------
1136
1137 /**
1138 * Close stream (apply post-processing if necessary, flush data and close).
1139 */
1140 void TWholeDomainOutputHDF5Stream::Close()
1141 {
1142 // the dataset is still opened
1143 if (HDF5_DatasetId != H5I_BADID)
1144 {
1145 HDF5_File.CloseDataset(HDF5_DatasetId);
1146 }
1147
1148 HDF5_DatasetId = H5I_BADID;
1149 }// end of Close
1150 //------------------------------------------------------------------------------
1151
1152
1153 //----------------------------------------------------------------------------//
1154 // TWholeDomainOutputHDF5Stream implementation //
1155 // protected methods //
1156 //----------------------------------------------------------------------------//
1157
1158
1159 /**
1160 * Flush the buffer down to the file at the actual position.
1161 */
1162 void TWholeDomainOutputHDF5Stream::FlushBufferToFile()
1163 {
1164 TDimensionSizes Size = SourceMatrix.GetDimensionSizes();
1165 TDimensionSizes Position(0,0,0);
1166
1167 // Not used for roNONE now!
1168 if (ReductionOp == roNONE)
1169 {
1170 Position.T = SampledTimeStep;
1171 Size.T = SampledTimeStep;
1172 }
1173
1174 HDF5_File.WriteHyperSlab(HDF5_DatasetId,
1175 Position,
1176 Size,
1177 StoreBuffer);
1178 SampledTimeStep++;
1179 }// end of FlushToFile
1180 //------------------------------------------------------------------------------
1181
1182
TDimensionSizes::Z
size_t Z
Z dimension size.
Definition: DimensionSizes.h:70
TBaseFloatMatrix::GetRawData
virtual float * GetRawData()
Get raw data out of the class (for direct kernel access).
Definition: BaseFloatMatrix.h:95
TIndexOutputHDF5Stream::SampledTimeStep
size_t SampledTimeStep
Time step to store (N/A for aggregated).
Definition: OutputHDF5Stream.h:226
TIndexMatrix::GetTotalNumberOfElementsInAllCuboids
size_t GetTotalNumberOfElementsInAllCuboids() const
Get the total number of elements to be sampled within all cuboids.
Definition: IndexMatrix.cpp:152
THDF5_File::CreateGroup
hid_t CreateGroup(const hid_t ParentGroup, const char *GroupName)
Create a HDF5 group at a specified place in the file tree.
Definition: HDF5_File.cpp:201
TWholeDomainOutputHDF5Stream::FlushBufferToFile
virtual void FlushBufferToFile()
Flush the buffer to the file.
Definition: OutputHDF5Stream.cpp:1162
TCuboidOutputHDF5Stream::CuboidsInfo
std::vector< TCuboidInfo > CuboidsInfo
vector keeping handles and positions of all cuboids
Definition: OutputHDF5Stream.h:298
TBaseOutputHDF5Stream::TReductionOperator
TReductionOperator
How to aggregate data.
Definition: OutputHDF5Stream.h:68
TCuboidOutputHDF5Stream::TCuboidOutputHDF5Stream
TCuboidOutputHDF5Stream(THDF5_File &HDF5_File, const char *HDF5_GroupName, const TRealMatrix &SourceMatrix, const TIndexMatrix &SensorMask, const TReductionOperator ReductionOp, float *BufferToReuse=NULL)
Constructor - links the HDF5 File, SourceMatrix, and SensorMask together.
Definition: OutputHDF5Stream.cpp:480
TParameters::GetStartTimeIndex
size_t GetStartTimeIndex() const
Get start time index for sensor recording.
Definition: Parameters.h:215
TBaseOutputHDF5Stream::HDF5_RootObjectName
char * HDF5_RootObjectName
Dataset name.
Definition: OutputHDF5Stream.h:151
TWholeDomainOutputHDF5Stream::Reopen
virtual void Reopen()
Reopen the output stream after restart and reload data.
Definition: OutputHDF5Stream.cpp:1007
TBaseFloatMatrix::GetTotalElementCount
virtual size_t GetTotalElementCount() const
Get element count of the matrix.
Definition: BaseFloatMatrix.h:70
TBaseOutputHDF5Stream::ReductionOp
const TReductionOperator ReductionOp
Reduction operator.
Definition: OutputHDF5Stream.h:155
THDF5_File::OpenGroup
hid_t OpenGroup(const hid_t ParentGroup, const char *GroupName)
Open a HDF5 group at a specified place in the file tree.
Definition: HDF5_File.cpp:229
TIndexOutputHDF5Stream::SensorMask
const TIndexMatrix & SensorMask
Sensor mask to sample data.
Definition: OutputHDF5Stream.h:221
TIndexMatrix::GetBottomRightCorner
TDimensionSizes GetBottomRightCorner(const size_t &index) const
Get the bottom right corner of the index-th cuboid.
Definition: IndexMatrix.h:116
TBaseOutputHDF5Stream::BufferReuse
bool BufferReuse
if true, the container reuses e.g. Temp_1_RS3D, Temp_2_RS3D, Temp_3_RS3D.
Definition: OutputHDF5Stream.h:158
TWholeDomainOutputHDF5Stream::Close
virtual void Close()
Close stream (apply post-processing if necessary, flush data and close).
Definition: OutputHDF5Stream.cpp:1140
THDF5_File::WriteCuboidToHyperSlab
void WriteCuboidToHyperSlab(const hid_t HDF5_Dataset_id, const TDimensionSizes &HyperslabPosition, const TDimensionSizes &CuboidPosition, const TDimensionSizes &CuboidSize, const TDimensionSizes &MatrixDimensions, const float *MatrixData)
Write a cuboid selected inside MatrixData into a Hyperslab.
Definition: HDF5_File.cpp:633
TBaseIndexMatrix::GetTotalElementCount
virtual size_t GetTotalElementCount() const
Get total element count of the matrix.
Definition: BaseIndexMatrix.h:71
TBaseIndexMatrix::GetRawData
virtual size_t * GetRawData()
Get raw data out of the class (for direct kernel access).
Definition: BaseIndexMatrix.h:90
TIndexOutputHDF5Stream::TIndexOutputHDF5Stream
TIndexOutputHDF5Stream(THDF5_File &HDF5_File, const char *HDF5_ObjectName, const TRealMatrix &SourceMatrix, const TIndexMatrix &SensorMask, const TReductionOperator ReductionOp, float *BufferToReuse=NULL)
Constructor - links the HDF5 dataset, SourceMatrix, and SensorMask together.
Definition: OutputHDF5Stream.cpp:216
TWholeDomainOutputHDF5Stream::Sample
virtual void Sample()
Sample data into buffer and apply reduction, or flush to disk (no sensor mask here).
Definition: OutputHDF5Stream.cpp:1042
TDimensionSizes::X
size_t X
X dimension size.
Definition: DimensionSizes.h:66
TIndexOutputHDF5Stream::Reopen
virtual void Reopen()
Reopen the output stream after restart and reload data.
Definition: OutputHDF5Stream.cpp:299
TIndexOutputHDF5Stream::Sample
virtual void Sample()
Sample data into buffer, apply reduction or flush to disk - based on a sensor mask.
Definition: OutputHDF5Stream.cpp:339
Parameters.h
The header file containing the parameters of the simulation.
TCuboidOutputHDF5Stream::SensorMask
const TIndexMatrix & SensorMask
Sensor mask to sample data.
Definition: OutputHDF5Stream.h:292
TBaseOutputHDF5Stream::PostProcess
virtual void PostProcess()
Apply post-processing on the buffer and flush it to the file.
Definition: OutputHDF5Stream.cpp:68
TCuboidOutputHDF5Stream::TCuboidInfo::HDF5_CuboidId
hid_t HDF5_CuboidId
ID of the dataset storing the given cuboid.
Definition: OutputHDF5Stream.h:280
THDF5_File::WriteHyperSlab
void WriteHyperSlab(const hid_t HDF5_Dataset_id, const TDimensionSizes &Position, const TDimensionSizes &Size, const float *Data)
Write a hyper-slab into the dataset - float dataset.
Definition: HDF5_File.cpp:467
TBaseOutputHDF5Stream::AllocateMemory
virtual void AllocateMemory()
A generic function to allocate memory - not used in the base class.
Definition: OutputHDF5Stream.cpp:119
TCuboidOutputHDF5Stream::SampledTimeStep
size_t SampledTimeStep
Timestep to store (N/A for aggregated).
Definition: OutputHDF5Stream.h:301
TBaseFloatMatrix::GetDimensionSizes
virtual TDimensionSizes GetDimensionSizes() const
Get dimension sizes of the matrix.
Definition: BaseFloatMatrix.h:64
TBaseOutputHDF5Stream::StoreBuffer
float * StoreBuffer
Temporary buffer for store - only if Buffer Reuse = false!
Definition: OutputHDF5Stream.h:162
TParameters::Get_t_index
size_t Get_t_index() const
Get simulation time step.
Definition: Parameters.h:91
TBaseOutputHDF5Stream::SourceMatrix
const TRealMatrix & SourceMatrix
Source matrix to be sampled.
Definition: OutputHDF5Stream.h:153
TIndexOutputHDF5Stream::Checkpoint
virtual void Checkpoint()
Checkpoint the stream.
Definition: OutputHDF5Stream.cpp:418
TIndexOutputHDF5Stream::FlushBufferToFile
virtual void FlushBufferToFile()
Flush the buffer to the file.
Definition: OutputHDF5Stream.cpp:450
TWholeDomainOutputHDF5Stream::~TWholeDomainOutputHDF5Stream
virtual ~TWholeDomainOutputHDF5Stream()
Destructor.
Definition: OutputHDF5Stream.cpp:965
THDF5_File::WriteMatrixDataType
void WriteMatrixDataType(const hid_t ParentGroup, const char *DatasetName, const THDF5_MatrixDataType &MatrixDataType)
Write matrix data type into the dataset under a specified group.
Definition: HDF5_File.cpp:1116
OutputHDF5Stream.h
The header file of classes responsible for storing output quantities into the output HDF5 file...
THDF5_File::WriteMatrixDomainType
void WriteMatrixDomainType(const hid_t ParentGroup, const char *DatasetName, const THDF5_MatrixDomainType &MatrixDomainType)
Write matrix domain type into the dataset under the root group.
Definition: HDF5_File.cpp:1135
TParameters
Class storing all parameters of the simulation.
Definition: Parameters.h:51
TIndexMatrix::GetTopLeftCorner
TDimensionSizes GetTopLeftCorner(const size_t &index) const
Get the top left corner of the index-th cuboid.
Definition: IndexMatrix.h:99
TCuboidOutputHDF5Stream::PostProcess
virtual void PostProcess()
Apply post-processing on the buffer and flush it to the file.
Definition: OutputHDF5Stream.cpp:799
THDF5_File::GetRootGroup
hid_t GetRootGroup() const
Get handle to the root group.
Definition: HDF5_File.h:581
TCuboidOutputHDF5Stream::Create
virtual void Create()
Create a HDF5 stream and allocate data for it.
Definition: OutputHDF5Stream.cpp:515
ErrorMessages.h
The header file containing all error messages of the project.
THDF5_File::CreateFloatDataset
hid_t CreateFloatDataset(const hid_t ParentGroup, const char *DatasetName, const TDimensionSizes &DimensionSizes, const TDimensionSizes &ChunkSizes, const size_t CompressionLevel)
Create the HDF5 dataset at a specified place in the file tree (3D/4D).
Definition: HDF5_File.cpp:291
TDimensionSizes::GetElementCount
size_t GetElementCount() const
Get element count, in 3D only spatial domain, in 4D with time.
Definition: DimensionSizes.h:93
THDF5_File::OpenDataset
hid_t OpenDataset(const hid_t ParentGroup, const char *DatasetName)
Open the HDF5 dataset at a specified place in the file tree.
Definition: HDF5_File.cpp:264
TBaseOutputHDF5Stream
Abstract base class for output data streams (sampled data).
Definition: OutputHDF5Stream.h:55
TCuboidOutputHDF5Stream::Checkpoint
virtual void Checkpoint()
Checkpoint the stream and close.
Definition: OutputHDF5Stream.cpp:811
TIndexOutputHDF5Stream::Close
virtual void Close()
Close stream (apply post-processing if necessary, flush data and close).
Definition: OutputHDF5Stream.cpp:429
TBaseOutputHDF5Stream::FreeMemory
virtual void FreeMemory()
A generic function to free memory - not used in the base class.
Definition: OutputHDF5Stream.cpp:184
TRealMatrix
The class for real matrices.
Definition: RealMatrix.h:48
TDimensionSizes::Y
size_t Y
Y dimension size.
Definition: DimensionSizes.h:68
TBaseOutputHDF5Stream::ChunkSize_4MB
static const size_t ChunkSize_4MB
chunk size of 4MB in number of float elements.
Definition: OutputHDF5Stream.h:165
TCuboidOutputHDF5Stream::TCuboidInfo
This structure information about a HDF5 dataset (one cuboid). Namely, its HDF5_ID, Starting position in a lineup buffer.
Definition: OutputHDF5Stream.h:277
THDF5_File::ReadCompleteDataset
void ReadCompleteDataset(const hid_t ParentGroup, const char *DatasetName, const TDimensionSizes &DimensionSizes, float *Data)
Read data from the dataset under a specified group - float dataset.
Definition: HDF5_File.cpp:954
TParameters::Get_Nt
size_t Get_Nt() const
Get Nt value.
Definition: Parameters.h:89
TWholeDomainOutputHDF5Stream::Checkpoint
virtual void Checkpoint()
Checkpoint the stream and close.
Definition: OutputHDF5Stream.cpp:1130
TIndexMatrix
The class for 64b unsigned integers (indices). It is used for sensor_mask_index or sensor_corners_mas...
Definition: IndexMatrix.h:50
TWholeDomainOutputHDF5Stream::PostProcess
virtual void PostProcess()
Apply post-processing on the buffer and flush it to the file.
Definition: OutputHDF5Stream.cpp:1118
TDimensionSizes::T
size_t T
Number of time steps (for time series datasets).
Definition: DimensionSizes.h:72
THDF5_File::CloseGroup
void CloseGroup(const hid_t Group)
Close HDF5 group.
Definition: HDF5_File.cpp:251
TWholeDomainOutputHDF5Stream::SampledTimeStep
size_t SampledTimeStep
Time step to store (N/A for aggregated).
Definition: OutputHDF5Stream.h:355
TCuboidOutputHDF5Stream::Sample
virtual void Sample()
Sample data into buffer and apply reduction, or flush to disk - based on a sensor mask...
Definition: OutputHDF5Stream.cpp:614
TCuboidOutputHDF5Stream::Close
virtual void Close()
Close stream (apply post-processing if necessary, flush data and close).
Definition: OutputHDF5Stream.cpp:823
TParameters::GetCompressionLevel
size_t GetCompressionLevel() const
Get compression level.
Definition: Parameters.h:208
TBaseOutputHDF5Stream::BufferSize
size_t BufferSize
Buffer size.
Definition: OutputHDF5Stream.h:160
TCuboidOutputHDF5Stream::TCuboidInfo::StartingPossitionInBuffer
size_t StartingPossitionInBuffer
Having a single buffer for all cuboids, where this one starts.
Definition: OutputHDF5Stream.h:282
TCuboidOutputHDF5Stream::HDF5_GroupId
hid_t HDF5_GroupId
Handle to a HDF5 dataset.
Definition: OutputHDF5Stream.h:295
TBaseIndexMatrix::GetDimensionSizes
struct TDimensionSizes GetDimensionSizes() const
Get dimension sizes of the matrix.
Definition: BaseIndexMatrix.h:65
DATA_ALIGNMENT
const int DATA_ALIGNMENT
memory alignment for SSE, SSE2, SSE3, SSE4 (16B)
Definition: DimensionSizes.h:53
TWholeDomainOutputHDF5Stream::HDF5_DatasetId
hid_t HDF5_DatasetId
Handle to a HDF5 dataset.
Definition: OutputHDF5Stream.h:352
TCuboidOutputHDF5Stream::Reopen
virtual void Reopen()
Reopen the output stream after restart and reload data.
Definition: OutputHDF5Stream.cpp:551
TCuboidOutputHDF5Stream::CreateCuboidDataset
virtual hid_t CreateCuboidDataset(const size_t Index)
Create a new dataset for a given cuboid specified by index (order).
Definition: OutputHDF5Stream.cpp:853
TWholeDomainOutputHDF5Stream::Create
virtual void Create()
Create a HDF5 stream and allocate data for it.
Definition: OutputHDF5Stream.cpp:976
TIndexOutputHDF5Stream::HDF5_DatasetId
hid_t HDF5_DatasetId
Handle to a HDF5 dataset.
Definition: OutputHDF5Stream.h:223
Matrix_ERR_FMT_NotEnoughMemory
const char *const Matrix_ERR_FMT_NotEnoughMemory
Matrix class error message.
Definition: ErrorMessages.h:81
THDF5_File::CloseDataset
void CloseDataset(const hid_t HDF5_Dataset_id)
Close the HDF5 dataset.
Definition: HDF5_File.cpp:451
TIndexOutputHDF5Stream::PostProcess
virtual void PostProcess()
Apply post-processing on the buffer and flush it to the file.
Definition: OutputHDF5Stream.cpp:405
TCuboidOutputHDF5Stream::FlushBufferToFile
virtual void FlushBufferToFile()
Flush the buffer to the file.
Definition: OutputHDF5Stream.cpp:907
TBaseOutputHDF5Stream::HDF5_File
THDF5_File & HDF5_File
HDF5 file handle.
Definition: OutputHDF5Stream.h:149
TIndexOutputHDF5Stream::~TIndexOutputHDF5Stream
virtual ~TIndexOutputHDF5Stream()
Destructor.
Definition: OutputHDF5Stream.cpp:237
TWholeDomainOutputHDF5Stream::TWholeDomainOutputHDF5Stream
TWholeDomainOutputHDF5Stream(THDF5_File &HDF5_File, const char *HDF5_DatasetName, const TRealMatrix &SourceMatrix, const TReductionOperator ReductionOp, float *BufferToReuse=NULL)
Constructor - links the HDF5 File, SourceMatrix, and SensorMask together.
Definition: OutputHDF5Stream.cpp:947
THDF5_File
Class wrapping the HDF5 routines.
Definition: HDF5_File.h:506
TIndexOutputHDF5Stream::Create
virtual void Create()
Create a HDF5 stream and allocate data for it.
Definition: OutputHDF5Stream.cpp:250
TDimensionSizes
Structure with 4D dimension sizes (3 in space and 1 in time).
Definition: DimensionSizes.h:63
TCuboidOutputHDF5Stream::~TCuboidOutputHDF5Stream
virtual ~TCuboidOutputHDF5Stream()
Destructor.
Definition: OutputHDF5Stream.cpp:501
TParameters::GetInstance
static TParameters * GetInstance()
Get instance of the singleton class.
Definition: Parameters.cpp:74