High Performance Plasticity  0.5.0
spectralUtils.h
Go to the documentation of this file.
1 #ifndef HPP_SPECTRAL_UTILS_H
2 #define HPP_SPECTRAL_UTILS_H
3 
4 #include <mpi.h>
5 #include <cmath>
6 #include <vector>
7 #include <complex>
8 #include <fftw3-mpi.h>
9 #include <algorithm>
10 #include <numeric>
11 #include <fstream>
12 #include <memory>
13 #include <stdint.h>
14 #include <string.h>
15 #include <hpp/config.h>
16 #include <hpp/hdfUtils.h>
17 #include <hpp/tensor.h>
18 #include <hpp/mpiUtils.h>
19 #include <hpp/simdUtils.h>
20 #include <hpp/stdlibReplacements.h>
21 
22 namespace hpp
23 {
24 
32 struct FreeDelete {
33  void operator()(void* x) {
34  free(x);
35  }
36 };
37 
38 // FFTW THINGS //
39 
43 inline int fftwFlat2(int i0, int i1, int N0, int N1)
44 {
45  return i0*N1 + i1;
46 }
47 
48 inline int fftwFlat4(int i0, int i1, int i2, int i3, const std::vector<ptrdiff_t>& N)
49 {
50  return i0*N[1]*N[2]*N[3] + i1*N[2]*N[3] + i2*N[3] + i3;
51 }
52 
54  MPI_Comm comm;
55  size_t gridRank;
56  std::vector<ptrdiff_t> realDims;
57  std::vector<ptrdiff_t> realDimsPadded;
58  std::vector<ptrdiff_t> complexDims;
59 
60  // Global number of points
61  unsigned int NReal;
62  unsigned int NComplex;
63 
64  // Local number of points
65  ptrdiff_t localN0;
66  ptrdiff_t local0Start;
67  ptrdiff_t nLocalComplex;
68  std::vector<ptrdiff_t> complexDimsLocal;
69  std::vector<ptrdiff_t> realDimsLocal;
70  ptrdiff_t nLocalReal;
71 
72  // Local number of points in memory
73  ptrdiff_t nLocalComplexMem;
74  ptrdiff_t nLocalRealPadded;
75  std::vector<ptrdiff_t> realDimsPaddedLocal;
76 
77  // Local value arrays
78  double *in;
79  fftw_complex *out;
80  double *backin;
81 
82  // Plans
83  fftw_plan forwardPlan;
84  fftw_plan backwardPlan;
85 };
86 
87 FFTWConfigRealND prepareFFTWConfigRealND(const std::vector<ptrdiff_t>& realDims, MPI_Comm comm);
89 
90 inline double fftwComplexMag(fftw_complex comps)
91 {
92  return std::sqrt(std::pow(comps[0], 2) + std::pow(comps[1], 2));
93 }
94 
103 #define HPP_DEFAULT_ALIGNMENT 32
104 template <typename U>
106 {
107 public:
108  // Constructors
110  nDims = 0;
111  nTerms = 0;
112  }
113  SpectralDataset(const std::vector<std::vector<unsigned int>>& coordsList, const std::vector<std::complex<U>>& coeffList);
114 
115  // Getters
116  const std::shared_ptr<U>& getCoeffs() const {
117  return coeffs;
118  }
119  const std::shared_ptr<int>& getCoords() const {
120  return coords;
121  }
122  unsigned int getNDims() const {
123  return nDims;
124  }
125  unsigned int getNTerms() const {
126  return nTerms;
127  }
128 
129 private:
130  // Dataset dimensions
131  unsigned int nDims;
132 
133  // Number of terms in the truncated DFT
134  unsigned int nTerms;
135 
143  std::shared_ptr<int> coords;
144 
148  std::shared_ptr<U> coeffs;
149 
150  // The byte alignment of the data
151  unsigned int alignment = HPP_DEFAULT_ALIGNMENT;
152 };
153 
163 
164  // Constructors
165  SpectralDatasetID(const std::string& baseName, const std::vector<unsigned int>& component) : baseName(baseName), component(component) {
166  ;
167  }
168  explicit SpectralDatasetID(const std::string& baseName) : baseName(baseName) {
169  ;
170  }
171 
172  // Members
173  std::string baseName;
174  std::vector<unsigned int> component;
175 };
176 
177 // Comparison for use with std::map
178 bool operator<(const SpectralDatasetID& l, const SpectralDatasetID& r);
179 
180 // Operators defined for the sake of Boost Python vector indexing suite
181 bool operator==(const SpectralDatasetID& l, const SpectralDatasetID& r);
182 
183 // Set names
184 #define HPP_DEFAULT_UNIFIED_COORDS_NAME "unified_coords"
185 #define HPP_DEFAULT_COORDS_SUFFIX "_coords"
186 #define HPP_DEFAULT_COEFFS_SUFFIX "_vals"
187 
188 // Get derived names
189 inline std::string getCoordsName(std::string baseName) {
190  return baseName+HPP_DEFAULT_COORDS_SUFFIX;
191 }
192 inline std::string getCoeffsName(std::string baseName) {
193  return baseName+HPP_DEFAULT_COEFFS_SUFFIX;
194 }
195 
196 template <typename U>
197 std::string getComponentSuffix(const std::vector<U>& componentIdx) {
198  std::string suffix = "_";
199  for(auto component : componentIdx) {
200  suffix += std::to_string(component);
201  }
202  return suffix;
203 }
204 inline std::string getDefaultCoeffsDatasetName(SpectralDatasetID dsetID) {
205  std::string dsetName;
206  if (dsetID.component.size() == 0) {
207  dsetName = dsetID.baseName;
208  }
209  else {
210  dsetName = dsetID.baseName+getComponentSuffix(dsetID.component);
211  }
212  return getCoeffsName(dsetName);
213 }
214 
224 template <typename U>
226 {
227 public:
228  // Default constructor
230  ;
231  }
232 
233  // Construction from file
234  SpectralDatabase(std::string dbFilename, std::vector<std::string> dsetBasenames, unsigned int nTerms, MPI_Comm comm, unsigned int refineMult=1);
235 
236  // Direct construction
237  SpectralDatabase(std::vector<unsigned int> gd, std::vector<double> gs, std::vector<double> ge, std::map<SpectralDatasetID, SpectralDataset<U>> dsets);
238 
239  // IDFT
240  U getIDFTReal(std::string dsetBasename, std::vector<unsigned int> componentIdx, std::vector<unsigned int> spatialCoord) const;
241  U getIDFTReal(std::string dsetBasename, std::vector<unsigned int> spatialCoord) const;
242 
243  // Getters
244  const std::shared_ptr<U>& getExpTable() const {
245  return expTable;
246  }
247  const std::vector<unsigned int>& getGridDims() const {
248  return gridDims;
249  }
250  const std::vector<double>& getGridEnds() const {
251  return gridEnds;
252  }
253  const std::vector<double>& getGridLengths() const {
254  return gridLengths;
255  }
256  const std::vector<double>& getGridStarts() const {
257  return gridStarts;
258  }
259  const std::vector<double>& getGridSteps() const {
260  return gridSteps;
261  }
262  const hsize_t& getNDims() const {
263  return nDims;
264  }
266  return dsets.at(dsetID);
267  }
268  unsigned int getNDsets() const {
269  return dsets.size();
270  }
271  unsigned int getNTerms() const {
272  return dsets.begin()->second.getNTerms();
273  }
274 
275 private:
276  // Number of spatial dimensions
277  hsize_t nDims = 0;
278 
279  // Grid dimensions
280  std::vector<unsigned int> gridDims;
281 
282  // Grid spatial lengths
283  std::vector<double> gridStarts;
284  std::vector<double> gridEnds;
285  std::vector<double> gridLengths;
286  std::vector<double> gridSteps;
287 
288  // Datasets comprising the database
289  std::map<SpectralDatasetID, SpectralDataset<U>> dsets;
290 
291  // Tables of exponentials
292  std::shared_ptr<U> expTable;
293 
294  // Byte alignment for dynamically allocated memory
295  unsigned int alignment = HPP_DEFAULT_ALIGNMENT;
296 
297  // Load dataset
298  void loadDatasetSingleComponent(HDF5Handler& dbfile, std::string dsetBasename, std::vector<unsigned int> componentIdxUint, unsigned int nTerms, unsigned int refineMult=1);
299  void loadDataset(HDF5Handler& dbfile, std::string dsetBasename, unsigned int nTerms, unsigned int refineMult=1);
300 
301  // Generate exponential table
302  void generateExponentialTable();
303 };
304 
316 template <typename U>
318 {
319 public:
320  // Default constructor
322 
323  // Construction from file using given dataset IDs
324  SpectralDatabaseUnified(std::string dbFilename, std::vector<SpectralDatasetID> dsetIDs, unsigned int nTerms, MPI_Comm comm, unsigned int refineMult=1);
325  SpectralDatabaseUnified(std::string dbFilename, std::vector<SpectralDatasetID> dsetIDs, unsigned int nTerms, unsigned int refineMult=1);
326 
327  // Construction from file using discovered dataset IDs
328  SpectralDatabaseUnified(std::string dbFilename, unsigned int nTerms, MPI_Comm comm, unsigned int refineMult=1);
329 
330  bool hasDset(SpectralDatasetID dsetID) {return coeffs.count(dsetID) > 0;}
331 
332  // IDFT
333  U getIDFTReal(SpectralDatasetID dsetID, std::vector<unsigned int> spatialCoord) const;
334  U getIDFTReal(std::string dsetBasename, std::vector<unsigned int> componentIdx, std::vector<unsigned int> spatialCoord) const;
335  U getIDFTReal(std::string dsetFullname, std::vector<unsigned int> spatialCoord) const;
336 
337  // Getters
338 // const std::shared_ptr<U>& getExpTable() const {
339 // return expTable;
340 // }
341  const std::vector<unsigned int>& getGridDims() const {
342  return gridDims;
343  }
344  const std::vector<double>& getGridEnds() const {
345  return gridEnds;
346  }
347  const std::vector<double>& getGridLengths() const {
348  return gridLengths;
349  }
350  const std::vector<double>& getGridStarts() const {
351  return gridStarts;
352  }
353  const std::vector<double>& getGridSteps() const {
354  return gridSteps;
355  }
356  const hsize_t& getNDims() const {
357  return nDims;
358  }
359  std::shared_ptr<U> getCoeffs(const SpectralDatasetID& dsetID) const {
360  return coeffs.at(dsetID);
361  }
362  unsigned int getNTerms() const {return nTerms;}
363  const std::shared_ptr<int>& getCoords() const {return coords;}
364 private:
365  //
366  void constructFromHandler(HDF5Handler& dbFile, std::vector<SpectralDatasetID> dsetIDs, unsigned int nTerms, unsigned int refineMult=1);
367 
368  // Number of spatial dimensions
369  hsize_t nDims = 0;
370 
371  // Number of terms
372  unsigned int nTerms;
373 
374  // Grid dimensions
375  std::vector<unsigned int> gridDims;
376 
377  // Grid spatial lengths
378  std::vector<double> gridStarts;
379  std::vector<double> gridEnds;
380  std::vector<double> gridLengths;
381  std::vector<double> gridSteps;
382 
383  // Coordinate ordering that applied to all sets of coefficients
384  std::shared_ptr<int> coords;
385 
386  // The set of coefficients
387  std::map<SpectralDatasetID, std::shared_ptr<U>> coeffs;
388 
389  // Tables of exponentials
390  //std::shared_ptr<U> expTable;
391 
392  // Byte alignment for dynamically allocated memory
393  const unsigned int alignment = HPP_DEFAULT_ALIGNMENT;
394 
395  // Load dataset
396  void loadDatasets(HDF5Handler& dbfile, std::vector<SpectralDatasetID> dsetIDs, unsigned int nTerms, unsigned int refineMult=1);
397 
398  // Generate exponential table
399  //void generateExponentialTable();
400 };
401 
413 template <typename U>
414 void loadSpectralDatabase(hpp::HDF5Handler& infile, std::string dsetNameCoords, std::string dsetNameCoeffs, std::vector<hsize_t> componentIdx, std::vector<std::vector<unsigned int>>& coordsList, std::vector<std::complex<U>>& coeffList, unsigned int nTerms, unsigned int refineMult=1)
415 {
416  // Property list for reading in data
417  hid_t plist_in = infile.getPropertyListTransferIndependent();
418 
419  // Open datasets
420  hid_t dsetCoords = infile.getDataset(dsetNameCoords);
421  hid_t dsetCoeffs = infile.getDataset(dsetNameCoeffs);
422 
423  // Get dimensions
424  std::vector<hsize_t> dsetCoordsDims = hpp::getDatasetDims(dsetCoords);
425  std::vector<hsize_t> dsetCoeffsDims = hpp::getDatasetDims(dsetCoeffs);
426  unsigned int nCoeffs = dsetCoordsDims.end()[-2];
427  unsigned int nDims = dsetCoordsDims.back();
428  if (nCoeffs != dsetCoeffsDims.back()) throw std::runtime_error("Mismatch in dimensions of coeffs and coords.");
429  if (nTerms > nCoeffs) throw std::runtime_error("Requested more terms than exist in the dataset.");
430 
431  // Grid information
432  hid_t dsetGridDims = infile.getDataset("grid_dims");
433  std::vector<hsize_t> nDimsArray = hpp::getDatasetDims(dsetGridDims);
434  std::vector<unsigned int> gridDims(nDims);
435  std::vector<unsigned short int> gridDimsBuffer(nDims);
436  hpp::readSingleHDF5Array(dsetGridDims, plist_in, nDimsArray, gridDimsBuffer.data());
437  std::copy(gridDimsBuffer.begin(), gridDimsBuffer.end(), gridDims.data());
438 
439  // Read in raw data
440  std::vector<unsigned short int> coordsBuffer(nTerms*nDims);
441  std::vector<hpp::hdf_complex_t> coeffsBuffer(nTerms);
442 
443  hpp::HDFReadWriteParamsC coordsReadParams;
444  coordsReadParams.dataOffset = componentIdx;
445  coordsReadParams.dataOffset.push_back(0);
446  coordsReadParams.dataOffset.push_back(0);
447  coordsReadParams.dataCount = std::vector<hsize_t>(componentIdx.size(), 1);
448  coordsReadParams.dataCount.push_back(nTerms);
449  coordsReadParams.dataCount.push_back(nDims);
450  coordsReadParams.datatype = H5Dget_type(dsetCoords);
451  hpp::readHDF5SimpleArray(dsetCoords, plist_in, coordsReadParams, coordsBuffer.data());
452 
453  hpp::HDFReadWriteParamsC coeffsReadParams;
454  coeffsReadParams.dataOffset = componentIdx;
455  coeffsReadParams.dataOffset.push_back(0);
456  coeffsReadParams.dataCount = std::vector<hsize_t>(componentIdx.size(), 1);
457  coeffsReadParams.dataCount.push_back(nTerms);
458  coeffsReadParams.datatype = H5Dget_type(dsetCoeffs);
459  hpp::readHDF5SimpleArray(dsetCoeffs, plist_in, coeffsReadParams, coeffsBuffer.data());
460 
461  // Spectral refinement
462  if (refineMult == 0) {
463  throw std::runtime_error("Refinement multiplier must be strictly positive.");
464  } else {
465  for (auto&& dim : gridDims) {
466  dim *= refineMult;
467  }
468  }
469 
470  // Convert coords and coeffs
471  coordsList.resize(nTerms);
472  coeffList.resize(nTerms);
473 
474  // The number of actual numerical terms is less than the raw number requested,
475  // because using the fact that the data is real, we can simply double
476  // the terms that are supposed to have their conjugates included
477  unsigned int nTermsIncluded = 0; //number of analytic terms that have been included
478  unsigned int nTermsNumerical = 0; //number of numerical terms required to capture their effect
479  for (unsigned int i=0; nTermsIncluded<nTerms; i++) {
480  // Coords
481  coordsList[i].resize(nDims);
482  unsigned short int *start = coordsBuffer.data()+i*nDims;
483  unsigned short int *end = start+nDims;//Note that "end" is the address one *after* the final element
484  std::copy(start, end, coordsList[i].data());
485 
486  // Spectral refinement
487  for (auto&& coord : coordsList[i]) {
488  coord *= refineMult;
489  }
490 
491  // Coeffs
492  hpp::hdf_complex_t rawVal = coeffsBuffer[i];
493  coeffList[i] = std::complex<U>((U)rawVal.r, (U)rawVal.i);
494  nTermsIncluded++;
495 
496  // Add complex conjugates
497  bool shouldAddConjugate = true;
498 
499  // In the case where we're double counting the final dimension
500  if (coordsList[i].back() == 0) {
501  shouldAddConjugate = false;
502  }
503  // In the cases of an even final dimension, remove the conjugate
504  // cases where we're in the middle
505  if (gridDims.back()%2 == 0 && coordsList[i].back()*2 == gridDims.back()) {
506  shouldAddConjugate = false;
507  }
508 
509  if (shouldAddConjugate) {
510  if (nTermsIncluded<nTerms) {
511  // Add conjugate term for most recent entry
512  coeffList[i] *= (U)2.0;
513  nTermsIncluded++;
514  }
515  }
516 
517  // We've added a numerical term
518  nTermsNumerical++;
519  }
520 
521  // Size down to only the number of "effective" terms needed
522  coordsList.resize(nTermsNumerical);
523  coeffList.resize(nTermsNumerical);
524 }
525 
530 template <typename U>
531 std::complex<U> TruncatedIFFTNDSingleSquare(const unsigned int spatialDim, const std::vector<std::complex<U>>& expTable, const std::vector<std::vector<unsigned int>>& spectralCoordsList, const std::vector<std::complex<U>>& coeffs, std::vector<unsigned int> spatialCoord, unsigned int nTerms)
532 {
533  // Size checks
534  unsigned int nDims = spatialCoord.size();
535  unsigned int nCoeffs = spectralCoordsList.size();
536  if (coeffs.size() != nCoeffs) throw std::runtime_error("Mismatch between number of coordinates and coefficients.");
537  if (nTerms > nCoeffs) {
538  std::string errString = "Requested more terms than have been loaded: ";
539  errString += std::to_string(nTerms) + " > " + std::to_string(nCoeffs);
540  throw std::runtime_error(errString);
541  }
542 
543  // Restore
544  std::complex<U> val = 0.0;
545  std::complex<U> iUnit(0, 1);
546  std::complex<U> seriesTerm;
547  for (unsigned int iCoeff=0; iCoeff<nTerms; iCoeff++) {
548  // Add terms
549  unsigned int expFactorInt = 0;
550  for (unsigned int iDim=0; iDim<nDims; iDim++) {
551  expFactorInt += spectralCoordsList[iCoeff][iDim]*spatialCoord[iDim];
552  }
553 
554  // Range reduce inputs
555  expFactorInt = expFactorInt % spatialDim;
556  seriesTerm = coeffs[iCoeff]*expTable[expFactorInt];
557 
558  // Add actual terms
559  val += seriesTerm;
560  }
561 
562  // Return
563  return val;
564 }
565 
566 template <typename U>
567 U TruncatedIFFTNDSingleSquareReal(const unsigned int spatialDim, const std::vector<std::complex<U>>& expTable, const std::vector<std::vector<unsigned int>>& spectralCoordsList, const std::vector<std::complex<U>>& coeffs, std::vector<unsigned int> spatialCoord, unsigned int nTerms)
568 {
569  // Size checks
570  unsigned int nDims = spatialCoord.size();
571  unsigned int nCoeffs = spectralCoordsList.size();
572  if (coeffs.size() != nCoeffs) throw std::runtime_error("Mismatch between number of coordinates and coefficients.");
573  if (nTerms > nCoeffs) throw std::runtime_error("Requested more terms than have been loaded.");
574 
575  // Restore
576  U val = 0.0;
577  std::complex<U> coeff;
578  std::complex<U> expVal;
579  for (unsigned int iCoeff=0; iCoeff<nTerms; iCoeff++) {
580  // Add terms
581  unsigned int expFactorInt = 0;
582  for (unsigned int iDim=0; iDim<nDims; iDim++) {
583  expFactorInt += spectralCoordsList[iCoeff][iDim]*spatialCoord[iDim];
584  }
585 
586  // Range reduce inputs
587  expFactorInt = expFactorInt % spatialDim;
588 
589  // Operands
590  coeff = coeffs[iCoeff];
591  expVal = expTable[expFactorInt];
592  U seriesTerm = std::real(coeff)*std::real(expVal) - std::imag(coeff)*std::imag(expVal);
593 
594  // Add actual terms
595  val += seriesTerm;
596  }
597 
598  // Return
599  return val;
600 }
601 
606 template <typename U>
607 U TruncatedIFFTNDSingleSquareRealScalar(const unsigned int nDims, const unsigned int spatialDim, const U expTable[], const int spectralCoordsList[], const U coeffs[], std::vector<unsigned int> spatialCoord, unsigned int nTerms)
608 {
609  U val = 0.0;
610  for (unsigned int iCoeff=0; iCoeff<nTerms; iCoeff++) {
611  // Add terms
612  int expFactorInt = 0;
613  for (unsigned int iDim=0; iDim<nDims; iDim++) {
614  expFactorInt += spectralCoordsList[nDims*iCoeff+iDim]*spatialCoord[iDim];
615  }
616 
617  // Operands
618  U seriesTerm = coeffs[2*iCoeff]*expTable[2*expFactorInt] - coeffs[2*iCoeff+1]*expTable[2*expFactorInt+1];
619 
620  // Add actual terms
621  val += seriesTerm;
622  }
623 
624  // Return
625  return val;
626 }
627 
628 // Without a lookup table of complex exponentials
629 // Scalar processor implementation
630 template <typename U>
631 U TruncatedIFFTNDSingleSquareRealScalar(const unsigned int nDims, const unsigned int spatialDim, const int spectralCoordsList[], const U coeffs[], std::vector<unsigned int> spatialCoord, unsigned int nTerms)
632 {
633  U val = 0.0;
634  for (unsigned int iCoeff=0; iCoeff<nTerms; iCoeff++) {
635  // Add terms
636  int expFactorInt = 0;
637  for (unsigned int iDim=0; iDim<nDims; iDim++) {
638  expFactorInt += spectralCoordsList[nDims*iCoeff+iDim]*spatialCoord[iDim];
639  }
640 
641  // Range reduce
642  expFactorInt = expFactorInt % spatialDim;
643 
644  // Evaluate term
645  U expValRe = std::cos(2*expFactorInt*M_PI/spatialDim);
646  U expValIm = std::sin(2*expFactorInt*M_PI/spatialDim);
647  U seriesTerm = coeffs[2*iCoeff]*expValRe - coeffs[2*iCoeff+1]*expValIm;
648 
649  // Add actual terms
650  val += seriesTerm;
651  }
652 
653  // Return
654  return val;
655 }
656 
660 #ifdef HPP_USE_AVX
661 template <typename U>
662 U TruncatedIFFT4DSingleSquareRealAVX(const unsigned int spatialDim, const U expTable[], const int spectralCoordsList[], const U coeffs[], std::vector<unsigned int> spatialCoord, unsigned int nTerms)
663 {
664  __m256 productsSumVecF = _mm256_set_ps(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
665  __m256d productsSumVecD = _mm256_set_pd(0.0, 0.0, 0.0, 0.0);
666  __m128i spatialCoordVec = _mm_set_epi32((int)spatialCoord[3],(int)spatialCoord[2],(int)spatialCoord[1],(int)spatialCoord[0]);
667  __m128i twos = _mm_set_epi32(2,2,2,2);
668  unsigned int nChunks = nTerms/4;
669  for (unsigned int iChunk=0; iChunk<nChunks; iChunk++) {
670  const unsigned int iCoeff0 = iChunk*4;
671  const unsigned int iCoeff1 = iChunk*4+1;
672  const unsigned int iCoeff2 = iChunk*4+2;
673  const unsigned int iCoeff3 = iChunk*4+3;
674 
675  // Products of spectral and spatial coordinates
676  __m128i coordsVec = _mm_load_si128((__m128i*)(spectralCoordsList+4*iCoeff0));
677  // coordsVec = [coords[iCoeff0][0],coords[iCoeff0][1],coords[iCoeff0][2],coords[iCoeff0][3]]
678  __m128i coordProdsVec0 = _mm_mullo_epi32(coordsVec, spatialCoordVec);
679  // coordProdsVec0 = [coords[iCoeff0][0]*s[0],coords[iCoeff0][1]*s[1],coords[iCoeff0][2]*s[2],coords[iCoeff0][3]*s[3]]
680 
681  coordsVec = _mm_load_si128((__m128i*)(spectralCoordsList+4*iCoeff1));
682  __m128i coordProdsVec1 = _mm_mullo_epi32(coordsVec, spatialCoordVec);
683 
684  coordsVec = _mm_load_si128((__m128i*)(spectralCoordsList+4*iCoeff2));
685  __m128i coordProdsVec2 = _mm_mullo_epi32(coordsVec, spatialCoordVec);
686 
687  coordsVec = _mm_load_si128((__m128i*)(spectralCoordsList+4*iCoeff3));
688  __m128i coordProdsVec3 = _mm_mullo_epi32(coordsVec, spatialCoordVec);
689 
690  // Combined
691  __m128i addedPairsVec01 = _mm_hadd_epi32(coordProdsVec0, coordProdsVec1);
692  // addedPairsVec01 =
693  // [coords[iCoeff0][0]*s[0]+coords[iCoeff0][1]*s[1],
694  // coords[iCoeff0][2]*s[2]+coords[iCoeff0][3]*s[3],
695  // coords[iCoeff1][0]*s[0]+coords[iCoeff1][1]*s[1],
696  // coords[iCoeff1][2]*s[2]+coords[iCoeff1][3]*s[3]]
697  __m128i addedPairsVec23 = _mm_hadd_epi32(coordProdsVec2, coordProdsVec3);
698  // addedPairsVec23 =
699  // [coords[iCoeff2][0]*s[0]+coords[iCoeff2][1]*s[1],
700  // coords[iCoeff2][2]*s[2]+coords[iCoeff2][3]*s[3],
701  // coords[iCoeff3][0]*s[0]+coords[iCoeff3][1]*s[1],
702  // coords[iCoeff3][2]*s[2]+coords[iCoeff3][3]*s[3]]
703  __m128i fullyAddedVec0123 = _mm_hadd_epi32(addedPairsVec01, addedPairsVec23);
704  // fullyAddedVec0123 =
705  // [coords[iCoeff0][0]*s[0]+coords[iCoeff0][1]*s[1]+coords[iCoeff0][2]*s[2]+coords[iCoeff0][3]*s[3],
706  // coords[iCoeff1][0]*s[0]+coords[iCoeff1][1]*s[1]+coords[iCoeff1][2]*s[2]+coords[iCoeff1][3]*s[3],
707  // coords[iCoeff2][0]*s[0]+coords[iCoeff2][1]*s[1]+coords[iCoeff2][2]*s[2]+coords[iCoeff2][3]*s[3],
708  // coords[iCoeff3][0]*s[0]+coords[iCoeff3][1]*s[1]+coords[iCoeff3][2]*s[2]+coords[iCoeff3][3]*s[3]]
709  fullyAddedVec0123 = _mm_mullo_epi32(fullyAddedVec0123, twos);
710  int32_t *expFac = (int32_t*)&fullyAddedVec0123;
711 
712  // Add up products
713  // FLOAT
714  if (std::is_same<U, float>::value) {
715  __m256 coeffVecF = _mm256_load_ps((float*)coeffs+2*iCoeff0);
716  __m256 expValVecF = _mm256_loadu4_m64((float*)expTable+expFac[3], (float*)expTable+expFac[2], (float*)expTable+expFac[1], (float*)expTable+expFac[0]);
717  __m256 productsVecF = _mm256_mul_ps(coeffVecF, expValVecF);
718  productsSumVecF = _mm256_add_ps(productsSumVecF, productsVecF);
719  // DOUBLE
720  } else if (std::is_same<U, double>::value) {
721  // First set
722  __m256d coeffVecD = _mm256_load_pd((double*)coeffs+2*iCoeff0);
723  __m256d expValVecD = _mm256_loadu2_m128d((double*)expTable+expFac[1], (double*)expTable+expFac[0]);
724  __m256d productsVecD = _mm256_mul_pd(coeffVecD, expValVecD);
725  productsSumVecD = _mm256_add_pd(productsSumVecD, productsVecD);
726 
727  // Second set
728  coeffVecD = _mm256_load_pd((double*)coeffs+2*iCoeff2);
729  expValVecD = _mm256_loadu2_m128d((double*)expTable+expFac[3], (double*)expTable+expFac[2]);
730  productsVecD = _mm256_mul_pd(coeffVecD, expValVecD);
731  productsSumVecD = _mm256_add_pd(productsSumVecD, productsVecD);
732  }
733  }
734 
735  // Return
736  // FLOAT
737  if (std::is_same<U, float>::value) {
738  float *productsSum = (float*)&productsSumVecF;
739  return productsSum[0] - productsSum[1] + productsSum[2] - productsSum[3] + productsSum[4] - productsSum[5] + productsSum[6] - productsSum[7];
740  // DOUBLE
741  } else if (std::is_same<U, double>::value) {
742  double *productsSum = (double*)&productsSumVecD;
743  return productsSum[0] - productsSum[1] + productsSum[2] - productsSum[3];
744  }
745 }
746 #endif /*HPP_USE_AVX*/
747 
751 #ifdef HPP_USE_AVX2
752 template <typename U>
753 U TruncatedIFFT4DSingleSquareRealAVX2(const unsigned int spatialDim, const U expTable[], const int spectralCoordsList[], const U coeffs[], std::vector<unsigned int> spatialCoord, unsigned int nTerms)
754 {
755  __m256 productsSumVecF = _mm256_set_ps(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
756  __m256d productsSumVecD = _mm256_set_pd(0.0, 0.0, 0.0, 0.0);
757  __m256i spatialCoordVec = _mm256_set_epi32((int)spatialCoord[3],(int)spatialCoord[2],(int)spatialCoord[1],(int)spatialCoord[0],(int)spatialCoord[3],(int)spatialCoord[2],(int)spatialCoord[1],(int)spatialCoord[0]);
758  __m256i twos = _mm256_set_epi32(2,2,2,2,2,2,2,2);
759  unsigned int nChunks = nTerms/8;
760  for (unsigned int iChunk=0; iChunk<nChunks; iChunk++) {
761  const unsigned int iCoeff0 = iChunk*8;
762  const unsigned int iCoeff2 = iChunk*8+2;
763  const unsigned int iCoeff4 = iChunk*8+4;
764  const unsigned int iCoeff6 = iChunk*8+6;
765 
766  // Products of spectral and spatial coordinates
767  __m256i coordsVec = _mm256_load_si256((__m256i*)(spectralCoordsList+4*iCoeff0));
768  // coordsVec =
769  // [coords[iCoeff0][0],coords[iCoeff0][1],coords[iCoeff0][2],coords[iCoeff0][3],
770  // coords[iCoeff1][0],coords[iCoeff1][1],coords[iCoeff1][2],coords[iCoeff1][3]]
771  __m256i coordProdsVec01 = _mm256_mullo_epi32(coordsVec, spatialCoordVec);
772  // coordProdsVec01 =
773  // [coords[iCoeff0][0]*s[0],coords[iCoeff0][1]*s[1],coords[iCoeff0][2]*s[2],coords[iCoeff0][3]*s[3],
774  // coords[iCoeff1][0]*s[0],coords[iCoeff1][1]*s[1],coords[iCoeff1][2]*s[2],coords[iCoeff1][3]*s[3]]
775  // Combined
776  coordsVec = _mm256_load_si256((__m256i*)(spectralCoordsList+4*iCoeff2));
777  __m256i coordProdsVec23 = _mm256_mullo_epi32(coordsVec, spatialCoordVec);
778 
779  coordsVec = _mm256_load_si256((__m256i*)(spectralCoordsList+4*iCoeff4));
780  __m256i coordProdsVec45 = _mm256_mullo_epi32(coordsVec, spatialCoordVec);
781 
782  coordsVec = _mm256_load_si256((__m256i*)(spectralCoordsList+4*iCoeff6));
783  __m256i coordProdsVec67 = _mm256_mullo_epi32(coordsVec, spatialCoordVec);
784 
785  // Note that the ordering produced by _mm256_hadd_epi32 is awkward. The explanation below, though bizarre-looking, is correct
786  __m256i addedPairsVec0213 = _mm256_hadd_epi32(coordProdsVec01, coordProdsVec23);
787  // addedPairsVec0213 =
788  // coords[iCoeff0][0]*s[0]+coords[iCoeff0][1]*s[1], coords[iCoeff0][2]*s[2]+coords[iCoeff0][3]*s[3],
789  // coords[iCoeff2][0]*s[0]+coords[iCoeff2][1]*s[1], coords[iCoeff2][2]*s[2]+coords[iCoeff2][3]*s[3],
790  // coords[iCoeff1][0]*s[0]+coords[iCoeff1][1]*s[1], coords[iCoeff1][2]*s[2]+coords[iCoeff1][3]*s[3],
791  // coords[iCoeff3][0]*s[0]+coords[iCoeff3][1]*s[1], coords[iCoeff3][2]*s[2]+coords[iCoeff3][3]*s[3],
792  __m256i addedPairsVec4657 = _mm256_hadd_epi32(coordProdsVec45, coordProdsVec67);
793  __m256i fullyAddedVec02461357 = _mm256_hadd_epi32(addedPairsVec0213, addedPairsVec4657);
794  // The mapping from logical indices to array indices is now
795  // 0->0
796  // 1->4
797  // 2->1
798  // 3->5
799  // 4->2
800  // 5->6
801  // 6->3
802  // 7->7
803  fullyAddedVec02461357 = _mm256_mullo_epi32(fullyAddedVec02461357, twos);
804  int32_t *expFac = (int32_t*)&fullyAddedVec02461357;
805 
806  // Add up products
807  // FLOAT
808  if (std::is_same<U, float>::value) {
809  // First set
810  __m256 coeffVecF = _mm256_load_ps((float*)coeffs+2*iCoeff0);
811  __m256 expValVecF = _mm256_loadu4_m64((float*)expTable+expFac[5], (float*)expTable+expFac[1], (float*)expTable+expFac[4], (float*)expTable+expFac[0]);
812  __m256 productsVecF = _mm256_mul_ps(coeffVecF, expValVecF);
813  productsSumVecF = _mm256_add_ps(productsSumVecF, productsVecF);
814 
815  // Second set
816  coeffVecF = _mm256_load_ps((float*)coeffs+2*iCoeff4);
817  expValVecF = _mm256_loadu4_m64((float*)expTable+expFac[7], (float*)expTable+expFac[3], (float*)expTable+expFac[6], (float*)expTable+expFac[2]);
818  productsVecF = _mm256_mul_ps(coeffVecF, expValVecF);
819  productsSumVecF = _mm256_add_ps(productsSumVecF, productsVecF);
820  // DOUBLE
821  } else if (std::is_same<U, double>::value) {
822  // First set
823  __m256d coeffVecD = _mm256_load_pd((double*)coeffs+2*iCoeff0);
824  __m256d expValVecD = _mm256_loadu2_m128d((double*)expTable+expFac[4], (double*)expTable+expFac[0]);
825  __m256d productsVecD = _mm256_mul_pd(coeffVecD, expValVecD);
826  productsSumVecD = _mm256_add_pd(productsSumVecD, productsVecD);
827 
828  // Second set
829  coeffVecD = _mm256_load_pd((double*)coeffs+2*iCoeff2);
830  expValVecD = _mm256_loadu2_m128d((double*)expTable+expFac[5], (double*)expTable+expFac[1]);
831  productsVecD = _mm256_mul_pd(coeffVecD, expValVecD);
832  productsSumVecD = _mm256_add_pd(productsSumVecD, productsVecD);
833 
834  // Third set
835  coeffVecD = _mm256_load_pd((double*)coeffs+2*iCoeff4);
836  expValVecD = _mm256_loadu2_m128d((double*)expTable+expFac[6], (double*)expTable+expFac[2]);
837  productsVecD = _mm256_mul_pd(coeffVecD, expValVecD);
838  productsSumVecD = _mm256_add_pd(productsSumVecD, productsVecD);
839 
840  // Fourth set
841  coeffVecD = _mm256_load_pd((double*)coeffs+2*iCoeff6);
842  expValVecD = _mm256_loadu2_m128d((double*)expTable+expFac[7], (double*)expTable+expFac[3]);
843  productsVecD = _mm256_mul_pd(coeffVecD, expValVecD);
844  productsSumVecD = _mm256_add_pd(productsSumVecD, productsVecD);
845  }
846  }
847 
848  // Return
849  // FLOAT
850  if (std::is_same<U, float>::value) {
851  float *productsSum = (float*)&productsSumVecF;
852  return productsSum[0] - productsSum[1] + productsSum[2] - productsSum[3] + productsSum[4] - productsSum[5] + productsSum[6] - productsSum[7];
853  // DOUBLE
854  } else if (std::is_same<U, double>::value) {
855  double *productsSum = (double*)&productsSumVecD;
856  return productsSum[0] - productsSum[1] + productsSum[2] - productsSum[3];
857  }
858 }
859 #endif /*HPP_USE_AVX2*/
860 
871 template <typename U>
872 U TruncatedIFFT4DSingleSquareReal(const unsigned int spatialDim, const U expTable[], const int spectralCoordsList[], const U coeffs[], const std::vector<unsigned int>& spatialCoord, unsigned int nTerms)
873 {
874  // Architecture-specific implementations
875 #if defined HPP_USE_AVX2
876  return TruncatedIFFT4DSingleSquareRealAVX2(spatialDim, expTable, spectralCoordsList, coeffs, spatialCoord, nTerms);
877 #elif defined HPP_USE_AVX
878  return TruncatedIFFT4DSingleSquareRealAVX(spatialDim, expTable, spectralCoordsList, coeffs, spatialCoord, nTerms);
879 #else
880  return TruncatedIFFTNDSingleSquareRealScalar(4, spatialDim, expTable, spectralCoordsList, coeffs, spatialCoord, nTerms);
881 #endif
882 }
883 
884 template <typename U>
885 U TruncatedIFFTNDSingleSquareReal(const unsigned int nDims, const unsigned int spatialDim, const U expTable[], const int spectralCoordsList[], const U coeffs[], const std::vector<unsigned int>& spatialCoord, unsigned int nTerms)
886 {
887  // Architecture-specific implementations
889  return TruncatedIFFTNDSingleSquareRealScalar(nDims, spatialDim, expTable, spectralCoordsList, coeffs, spatialCoord, nTerms);
890 }
891 
892 template <typename U>
893 U TruncatedIFFT4DSingleSquareReal(const unsigned int spatialDim, const int spectralCoordsList[], const U coeffs[], const std::vector<unsigned int>& spatialCoord, unsigned int nTerms)
894 {
895  // Architecture-specific implementations
897  return TruncatedIFFTNDSingleSquareRealScalar(4, spatialDim, spectralCoordsList, coeffs, spatialCoord, nTerms);
898 }
899 
900 template <typename U>
901 U TruncatedIFFTNDSingleSquareReal(const unsigned int nDims, const unsigned int spatialDim, const int spectralCoordsList[], const U coeffs[], const std::vector<unsigned int>& spatialCoord, unsigned int nTerms)
902 {
903  // Architecture-specific implementations
905  return TruncatedIFFTNDSingleSquareRealScalar(nDims, spatialDim, spectralCoordsList, coeffs, spatialCoord, nTerms);
906 }
907 
908 void evaluateSpectralCompressionErrorFull(std::string rawDBName, std::string spectralDBName, std::string errorDBName, unsigned int nTermsMax, std::string outFilename, MPI_Comm comm);
909 
910 void evaluateSpectralCompressionErrorAxisSlice(std::string rawDBName, std::string spectralDBName, std::vector<std::string> dsetBasenames, unsigned int nTermsMax, unsigned int refineMult, std::vector<int> axisSlice, std::string outFilename, MPI_Comm comm);
911 
912 void evaluateSpectralCompressionErrorFullUnified(std::string rawDBName, std::string spectralDBName, std::string errorDBName, unsigned int nTermsMax, std::string outFilename, MPI_Comm comm);
913 
914 void evaluateSpectralCompressionErrorAxisSliceUnified(std::string rawDBName, std::string spectralDBName, std::vector<std::string> dsetBasenames, unsigned int nTermsMax, unsigned int refineMult, std::vector<int> axisSlice, std::string outFilename, MPI_Comm comm);
915 
916 
917 } //END NAMESPACE HPP
918 
919 #endif /* HPP_SPECTRAL_UTILS_H */
Definition: spectralUtils.h:317
std::vector< hsize_t > dataOffset
Definition: hdfUtils.h:98
SpectralDataset()
Definition: spectralUtils.h:109
std::vector< hsize_t > dataCount
Definition: hdfUtils.h:99
std::vector< unsigned int > component
Definition: spectralUtils.h:174
SpectralDataset< U > getDataset(const SpectralDatasetID &dsetID) const
Definition: spectralUtils.h:265
#define HPP_DEFAULT_COEFFS_SUFFIX
Definition: spectralUtils.h:186
SpectralDatabase()
Definition: spectralUtils.h:229
unsigned int getNTerms() const
Definition: spectralUtils.h:362
const std::shared_ptr< int > & getCoords() const
Definition: spectralUtils.h:119
std::map< SpectralDatasetID, std::shared_ptr< U > > coeffs
Definition: spectralUtils.h:387
unsigned int nTerms
Definition: spectralUtils.h:372
std::string baseName
Definition: spectralUtils.h:173
const std::vector< double > & getGridSteps() const
Definition: spectralUtils.h:259
#define _mm256_loadu2_m128d(hi, lo)
Definition: simdUtils.h:17
U TruncatedIFFTNDSingleSquareRealScalar(const unsigned int nDims, const unsigned int spatialDim, const U expTable[], const int spectralCoordsList[], const U coeffs[], std::vector< unsigned int > spatialCoord, unsigned int nTerms)
Scalar implementation of hpp.TruncatedIFFTNDSingleSquareReal.
Definition: spectralUtils.h:607
SpectralDatasetID(const std::string &baseName, const std::vector< unsigned int > &component)
Definition: spectralUtils.h:165
Definition: spectralUtils.h:161
const std::shared_ptr< U > & getExpTable() const
Definition: spectralUtils.h:244
const std::vector< double > & getGridEnds() const
Definition: spectralUtils.h:250
std::vector< ptrdiff_t > realDims
Definition: spectralUtils.h:56
Definition: casesUtils.cpp:4
void destroyConfigRealND(FFTWConfigRealND &cfg)
Definition: spectralUtils.cpp:62
U TruncatedIFFT4DSingleSquareReal(const unsigned int spatialDim, const U expTable[], const int spectralCoordsList[], const U coeffs[], const std::vector< unsigned int > &spatialCoord, unsigned int nTerms)
AVX implementation of hpp.TruncatedIFFT4DSingleSquareReal.
Definition: spectralUtils.h:872
bool hasDset(SpectralDatasetID dsetID)
Definition: spectralUtils.h:330
ptrdiff_t localN0
Definition: spectralUtils.h:65
#define HPP_DEFAULT_COORDS_SUFFIX
Definition: spectralUtils.h:185
std::string getDefaultCoeffsDatasetName(SpectralDatasetID dsetID)
Definition: spectralUtils.h:204
const std::vector< double > & getGridSteps() const
Definition: spectralUtils.h:353
hid_t datatype
Definition: hdfUtils.h:100
const std::vector< double > & getGridStarts() const
Definition: spectralUtils.h:350
Definition: hdfUtils.h:338
std::vector< double > gridSteps
Definition: spectralUtils.h:286
bool operator<(const SpectralDatasetID &l, const SpectralDatasetID &r)
Definition: spectralUtils.cpp:107
Definition: spectralUtils.h:225
const std::vector< double > & getGridLengths() const
Definition: spectralUtils.h:347
std::vector< hsize_t > getDatasetDims(hid_t dset_id)
Definition: hdfUtils.cpp:35
unsigned int getNDsets() const
Definition: spectralUtils.h:268
Definition: hdfUtils.h:97
unsigned int getNTerms() const
Definition: spectralUtils.h:125
const hsize_t & getNDims() const
Definition: spectralUtils.h:262
std::complex< U > TruncatedIFFTNDSingleSquare(const unsigned int spatialDim, const std::vector< std::complex< U >> &expTable, const std::vector< std::vector< unsigned int >> &spectralCoordsList, const std::vector< std::complex< U >> &coeffs, std::vector< unsigned int > spatialCoord, unsigned int nTerms)
TruncatedIFFTND where all dimensions have the same number of points.
Definition: spectralUtils.h:531
void operator()(void *x)
Definition: spectralUtils.h:33
ptrdiff_t nLocalReal
Definition: spectralUtils.h:70
std::vector< ptrdiff_t > realDimsLocal
Definition: spectralUtils.h:69
ptrdiff_t nLocalRealPadded
Definition: spectralUtils.h:74
fftw_plan forwardPlan
Definition: spectralUtils.h:83
A complex number type.
Definition: hdfUtils.h:62
Definition: spectralUtils.h:53
ptrdiff_t local0Start
Definition: spectralUtils.h:66
double r
Definition: hdfUtils.h:63
Header file for helper functions with HDF.
Header file for tensor classes.
bool operator==(const SpectralDatasetID &l, const SpectralDatasetID &r)
Definition: spectralUtils.cpp:132
std::string getCoeffsName(std::string baseName)
Definition: spectralUtils.h:192
std::vector< ptrdiff_t > complexDims
Definition: spectralUtils.h:58
std::shared_ptr< int > coords
Definition: spectralUtils.h:384
std::string getCoordsName(std::string baseName)
Definition: spectralUtils.h:189
SpectralDatasetID()
Definition: spectralUtils.h:162
const std::shared_ptr< int > & getCoords() const
Definition: spectralUtils.h:363
std::vector< ptrdiff_t > realDimsPaddedLocal
Definition: spectralUtils.h:75
double * in
Definition: spectralUtils.h:78
void loadSpectralDatabase(hpp::HDF5Handler &infile, std::string dsetNameCoords, std::string dsetNameCoeffs, std::vector< hsize_t > componentIdx, std::vector< std::vector< unsigned int >> &coordsList, std::vector< std::complex< U >> &coeffList, unsigned int nTerms, unsigned int refineMult=1)
Load a spectral database.
Definition: spectralUtils.h:414
std::vector< double > gridLengths
Definition: spectralUtils.h:380
std::map< SpectralDatasetID, SpectralDataset< U > > dsets
Definition: spectralUtils.h:289
#define HPP_DEFAULT_ALIGNMENT
Definition: spectralUtils.h:103
std::vector< double > gridStarts
Definition: spectralUtils.h:283
hid_t getPropertyListTransferIndependent()
Definition: hdfUtils.h:357
unsigned int NComplex
Definition: spectralUtils.h:62
ptrdiff_t nLocalComplexMem
Definition: spectralUtils.h:73
SpectralDatabaseUnified()
Definition: spectralUtils.h:321
std::vector< ptrdiff_t > realDimsPadded
Definition: spectralUtils.h:57
std::shared_ptr< U > expTable
Definition: spectralUtils.h:292
std::shared_ptr< int > coords
Definition: spectralUtils.h:143
ptrdiff_t nLocalComplex
Definition: spectralUtils.h:67
void evaluateSpectralCompressionErrorAxisSliceUnified(std::string rawDBName, std::string spectralDBName, std::vector< std::string > dsetBasenames, unsigned int nTermsMax, unsigned int refineMult, std::vector< int > axisSlice, std::string outFilename, MPI_Comm comm)
Evaluate the error incurred in the spectral reresentation of a database.
Definition: spectralUtils.cpp:1280
FFTWConfigRealND prepareFFTWConfigRealND(const std::vector< ptrdiff_t > &realDims, MPI_Comm comm)
Definition: spectralUtils.cpp:8
double fftwComplexMag(fftw_complex comps)
Definition: spectralUtils.h:90
double * backin
Definition: spectralUtils.h:80
void evaluateSpectralCompressionErrorFullUnified(std::string rawDBName, std::string spectralDBName, std::string errorDBName, unsigned int nTermsMax, std::string outFilename, MPI_Comm comm)
Definition: spectralUtils.cpp:923
int fftwFlat2(int i0, int i1, int N0, int N1)
Definition: spectralUtils.h:43
const std::vector< unsigned int > & getGridDims() const
Definition: spectralUtils.h:247
const std::vector< unsigned int > & getGridDims() const
Definition: spectralUtils.h:341
std::vector< double > gridStarts
Definition: spectralUtils.h:378
const std::vector< double > & getGridStarts() const
Definition: spectralUtils.h:256
MPI_Comm comm
Definition: spectralUtils.h:54
size_t gridRank
Definition: spectralUtils.h:55
std::shared_ptr< U > coeffs
Definition: spectralUtils.h:148
fftw_complex * out
Definition: spectralUtils.h:79
std::vector< ptrdiff_t > complexDimsLocal
Definition: spectralUtils.h:68
unsigned int nDims
Definition: spectralUtils.h:131
void readHDF5SimpleArray(hid_t dset_id, hid_t plist_id, HDFReadWriteParamsC parms, T *output)
Definition: hdfUtils.h:264
std::vector< double > gridEnds
Definition: spectralUtils.h:284
std::vector< unsigned int > gridDims
Definition: spectralUtils.h:280
SpectralDatasetID(const std::string &baseName)
Definition: spectralUtils.h:168
std::vector< unsigned int > gridDims
Definition: spectralUtils.h:375
std::string getComponentSuffix(const std::vector< U > &componentIdx)
Definition: spectralUtils.h:197
Definition: spectralUtils.h:32
std::shared_ptr< U > getCoeffs(const SpectralDatasetID &dsetID) const
Definition: spectralUtils.h:359
Definition: spectralUtils.h:105
unsigned int NReal
Definition: spectralUtils.h:61
const hsize_t & getNDims() const
Definition: spectralUtils.h:356
const std::shared_ptr< U > & getCoeffs() const
Definition: spectralUtils.h:116
const std::vector< double > & getGridEnds() const
Definition: spectralUtils.h:344
unsigned int getNDims() const
Definition: spectralUtils.h:122
void evaluateSpectralCompressionErrorAxisSlice(std::string rawDBName, std::string spectralDBName, std::vector< std::string > dsetBasenames, unsigned int nTermsMax, unsigned int refineMult, std::vector< int > axisSlice, std::string outFilename, MPI_Comm comm)
Evaluate the error incurred in the spectral reresentation of a database.
Definition: spectralUtils.cpp:1131
U TruncatedIFFTNDSingleSquareReal(const unsigned int spatialDim, const std::vector< std::complex< U >> &expTable, const std::vector< std::vector< unsigned int >> &spectralCoordsList, const std::vector< std::complex< U >> &coeffs, std::vector< unsigned int > spatialCoord, unsigned int nTerms)
Definition: spectralUtils.h:567
unsigned int nTerms
Definition: spectralUtils.h:134
double i
Definition: hdfUtils.h:64
const std::vector< double > & getGridLengths() const
Definition: spectralUtils.h:253
void evaluateSpectralCompressionErrorFull(std::string rawDBName, std::string spectralDBName, std::string errorDBName, unsigned int nTermsMax, std::string outFilename, MPI_Comm comm)
Definition: spectralUtils.cpp:731
std::vector< double > gridLengths
Definition: spectralUtils.h:285
fftw_plan backwardPlan
Definition: spectralUtils.h:84
std::vector< double > gridSteps
Definition: spectralUtils.h:381
Header file for implementations of stdlib functions that may be missing.
hid_t getDataset(std::string datasetName)
Definition: hdfUtils.cpp:129
unsigned int getNTerms() const
Definition: spectralUtils.h:271
int fftwFlat4(int i0, int i1, int i2, int i3, const std::vector< ptrdiff_t > &N)
Definition: spectralUtils.h:48
std::vector< double > gridEnds
Definition: spectralUtils.h:379
void readSingleHDF5Array(hid_t dset_id, hid_t plist_id, std::vector< hsize_t > gridOffset, std::vector< hsize_t > arrayDims, T *output)
Definition: hdfUtils.h:274