kspaceFirstOrder3D-OMP  1.2
The C++ implementation of the k-wave toolbox for the time-domain simulation of acoustic wave fields in 3D
IndexMatrix.cpp
Go to the documentation of this file.
1 /**
2  * @file IndexMatrix.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 containing the class for 64b integer matrices.
10  *
11  * @version kspaceFirstOrder3D 2.16
12  *
13  * @date 26 July 2011, 15:16 (created) \n
14  * 04 September 2017, 11:02 (revised)
15  *
16  * @copyright Copyright (C) 2017 Jiri Jaros and Bradley Treeby.
17  *
18  * This file is part of the C++ extension of the [k-Wave Toolbox](http://www.k-wave.org).
19  *
20  * This file is part of the k-Wave. k-Wave is free software: you can redistribute it and/or modify it under the terms
21  * of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the
22  * License, or (at your option) any later version.
23  *
24  * k-Wave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
25  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
26  * more details.
27  *
28  * You should have received a copy of the GNU Lesser General Public License along with k-Wave.
29  * If not, see [http://www.gnu.org/licenses/](http://www.gnu.org/licenses/).
30  */
31 
32 
34 #include <Logger/Logger.h>
35 
36 
37 using std::ios;
38 //--------------------------------------------------------------------------------------------------------------------//
39 //---------------------------------------------------- Constants -----------------------------------------------------//
40 //--------------------------------------------------------------------------------------------------------------------//
41 
42 
43 //--------------------------------------------------------------------------------------------------------------------//
44 //------------------------------------------------- Public methods ---------------------------------------------------//
45 //--------------------------------------------------------------------------------------------------------------------//
46 
47 /**
48  * Constructor allocating memory.
49  */
51  : BaseIndexMatrix()
52 {
53  initDimensions(dimensionSizes);
55 }// end of IndexMatrix
56 //----------------------------------------------------------------------------------------------------------------------
57 
58 /**
59  * Destructor.
60  */
62 {
63  freeMemory();
64 }// end of ~IndexMatrix
65 //----------------------------------------------------------------------------------------------------------------------
66 
67 /**
68  * Read data from HDF5 file (only from the root group).
69  */
71  MatrixName& matrixName)
72 {
73  // check the datatype
74  if (file.readMatrixDataType(file.getRootGroup(), matrixName) != Hdf5File::MatrixDataType::kLong)
75  {
76  throw std::ios::failure(Logger::formatMessage(kErrFmtMatrixNotIndex, matrixName.c_str()));
77  }
78 
79  // check the domain type
81  {
82  throw std::ios::failure(Logger::formatMessage(kErrFmtMatrixNotReal,matrixName.c_str()));
83  }
84 
85  // read data
86  file.readCompleteDataset(file.getRootGroup(), matrixName, mDimensionSizes, mData);
87 
88 }// end of readData
89 //----------------------------------------------------------------------------------------------------------------------
90 
91 /**
92  * Write data to HDF5 file.
93  */
95  MatrixName& matrixName,
96  const size_t compressionLevel)
97 {
98  // set chunks - may be necessary for long index based sensor masks
100  chunks.nz = 1;
101 
102  //1D matrices
103  if ((mDimensionSizes.ny == 1) && (mDimensionSizes.nz == 1))
104  {
105  // Chunk = 4MB
107  {
108  chunks.nx = kChunkSize1D4MB;
109  }
110  else if (mDimensionSizes.nx > 4 * kChunkSize1D1MB)
111  {
112  chunks.nx = kChunkSize1D1MB;
113  }
114  else if (mDimensionSizes.nx > 4 * kChunkSize1D256kB)
115  {
116  chunks.nx = kChunkSize1D256kB;
117  }
118  }
119 
120  // create dataset and write a slab
121  hid_t dataset = file.createDataset(file.getRootGroup(),
122  matrixName,
124  chunks,
126  compressionLevel);
127 
128  file.writeHyperSlab(dataset, DimensionSizes(0, 0, 0), mDimensionSizes, mData);
129 
130  file.closeDataset(dataset);
131 
132  // write data and domain types
135 }// end of writeData
136 //----------------------------------------------------------------------------------------------------------------------
137 
138 /**
139  * Get the top left corner of the index-th cuboid. Cuboids are stored as 6-tuples (two 3D
140  * coordinates). This gives the first three coordinates.
141  */
143 {
144  size_t x = mData[6 * index ];
145  size_t y = mData[6 * index + 1];
146  size_t z = mData[6 * index + 2];
147 
148  return DimensionSizes(x, y, z);
149 }// end of getTopLeftCorner
150 //----------------------------------------------------------------------------------------------------------------------
151 
152 /**
153  * Get the top bottom right of the index-th cuboid. Cuboids are stored as 6-tuples (two 3D
154  * coordinates). This gives the first three coordinates. This routine works only on the CPU side.
155 */
157 {
158  size_t x = mData[6 * index + 3];
159  size_t y = mData[6 * index + 4];
160  size_t z = mData[6 * index + 5];
161 
162  return DimensionSizes(x, y, z);
163 }// end of GetBottomRightCorner
164 //----------------------------------------------------------------------------------------------------------------------
165 
166 /**
167  * Recompute indeces, MATLAB -> C++.
168  */
170 {
171  #pragma omp parallel for simd
172  for (size_t i = 0; i < mSize; i++)
173  {
174  mData[i]--;
175  }
176 }// end of recomputeIndices
177 //----------------------------------------------------------------------------------------------------------------------
178 
179 /**
180  * Recompute indeces, C++ -> MATLAB.
181  */
183 {
184  #pragma omp parallel for simd
185  for (size_t i = 0; i < mSize; i++)
186  {
187  mData[i]++;
188  }
189 }// end of recomputeIndicesToMatlab
190 //----------------------------------------------------------------------------------------------------------------------
191 
192 /**
193  * Get total number of elements in all cuboids to be able to allocate output file.
194  */
196 {
197  size_t elementSum = 0;
198  for (size_t cuboidIdx = 0; cuboidIdx < mDimensionSizes.ny; cuboidIdx++)
199  {
200  elementSum += (getBottomRightCorner(cuboidIdx) - getTopLeftCorner(cuboidIdx)).nElements();
201  }
202 
203  return elementSum;
204 }// end of getSizeOfAllCuboids
205 //----------------------------------------------------------------------------------------------------------------------
206 
207 //--------------------------------------------------------------------------------------------------------------------//
208 //------------------------------------------------ Protected methods -------------------------------------------------//
209 //--------------------------------------------------------------------------------------------------------------------//
210 
211 //--------------------------------------------------------------------------------------------------------------------//
212 //------------------------------------------------- Private methods --------------------------------------------------//
213 //--------------------------------------------------------------------------------------------------------------------//
214 
215 /**
216  * Set necessary dimensions and auxiliary variables.
217  */
218 void IndexMatrix::initDimensions(const DimensionSizes& dimensionSizes)
219 {
220  mDimensionSizes = dimensionSizes;
221 
222  mSize = dimensionSizes.nx * dimensionSizes.ny * dimensionSizes.nz;
223 
224  mCapacity = mSize;
225 
226  mRowSize = dimensionSizes.nx;
227  mSlabSize = dimensionSizes.nx * dimensionSizes.ny;
228 }// end of initDimensions
229 //----------------------------------------------------------------------------------------------------------------------
void recomputeIndicesToMatlab()
Recompute indices C++ -> MATLAB.
size_t mRowSize
Size of 1D row in X dimension.
size_t mSize
Total number of elements.
ErrorMessage kErrFmtMatrixNotIndex
Matrix class error message.
virtual void readData(Hdf5File &file, MatrixName &matrixName)
Read matrix from HDF5 file.
Definition: IndexMatrix.cpp:70
hid_t getRootGroup() const
Get handle to the root group of the file.
Definition: Hdf5File.h:608
virtual void writeData(Hdf5File &file, MatrixName &matrixName, const size_t compressionLevel)
Write data into HDF5 file.
Definition: IndexMatrix.cpp:94
size_t nz
Number of elements in the z direction.
size_t * mData
Raw matrix data.
static constexpr size_t kChunkSize1D1MB
Number of elements to get 1MB block of data.
Definition: IndexMatrix.h:132
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
static constexpr size_t kChunkSize1D256kB
Number of elements to get 256KB block of data.
Definition: IndexMatrix.h:134
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
DimensionSizes getTopLeftCorner(const size_t &index) const
Get the top left corner of the index-th cuboid.
virtual void allocateMemory()
Aligned memory allocation (both on CPU and GPU).
virtual ~IndexMatrix()
Destructor.
Definition: IndexMatrix.cpp:61
The header file containing a class responsible for printing out info and error messages (stdout...
Class wrapping the HDF5 routines.
Definition: Hdf5File.h:490
static std::string formatMessage(const std::string &format, Args ... args)
C++-11 replacement for sprintf that works with std::string instead of char*.
Definition: Logger.h:157
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
The header file containing the class for 64b integer matrices.
const std::string MatrixName
Datatype for matrix names.
Definition: MatrixNames.h:39
Structure with 4D dimension sizes (3 in space and 1 in time).
MatrixDataType readMatrixDataType(const hid_t parentGroup, MatrixName &datasetName)
Read matrix data type from the dataset at a specified place in the file tree.
Definition: Hdf5File.cpp:821
void initDimensions(const DimensionSizes &dimensionSizes)
Init dimension.
The matrix is stored in fixed point point 64b wide format.
static constexpr size_t kChunkSize1D4MB
Number of elements to get 4MB block of data.
Definition: IndexMatrix.h:130
size_t ny
Number of elements in the y direction.
DimensionSizes getBottomRightCorner(const size_t &index) const
Get the top bottom right of the index-th cuboid.
void recomputeIndicesToCPP()
Recompute indices MATALAB->C++.
size_t mCapacity
Total number of allocated elements (in terms of size_t).
size_t mSlabSize
Size of a XY slab.
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
ErrorMessage kErrFmtMatrixNotReal
Matrix class error message.
IndexMatrix()=delete
Default constructor not allowed.
size_t nx
Number of elements in the x direction.
DimensionSizes mDimensionSizes
Dimension sizes.
Abstract base class for index based matrices defining basic interface. Higher dimensional matrices st...
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
MatrixDomainType readMatrixDomainType(const hid_t parentGroup, MatrixName &datasetName)
Read matrix dataset domain type at a specified place in the file tree.
Definition: Hdf5File.cpp:848
The matrix is defined on real domain.
size_t getSizeOfAllCuboids() const
Get total number of elements in all cuboids to be able to allocate output file.
virtual void freeMemory()
Memory deallocation (both on CPU and GPU)