IODA Bundle
ioda-test-chunks_and_filters.cpp
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2020 UCAR
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  */
7 #include <iostream>
8 #include <vector>
9 
11 #include "ioda/Engines/Factory.h"
12 #include "ioda/Exception.h"
13 #include "ioda/Group.h"
14 
15 template <class T>
16 bool testVar(ioda::Group &f, const std::string &varname, const std::vector<T> &data,
17  const std::vector<ioda::Dimensions_t> &dims, bool chunk, bool gzip,
18  bool szip) // NOLINT(google-runtime-references): f can be a non-const reference
19 {
20  try {
21  std::cout << "Testing variable " << varname << std::endl;
22  std::cout << "\tCreating..." << std::endl;
23  using namespace ioda;
25  if (chunk) {
26  params.chunk = true;
27  params.chunks = dims;
28  if (gzip) {
29  params.compressWithGZIP();
30  } else if (szip) {
31  params.compressWithSZIP();
32  }
33  }
34  ioda::Variable v_i = f.vars.create<T>(varname, dims, dims, params);
35  std::cout << "\t\tSuccess.\n\tWriting..." << std::endl;
36 
37  v_i.write<T>(data);
38 
39  std::cout << "\t\tSuccess.\n\tCheck that the variable's chunking options match the reference."
40  << std::endl;
41 
42  ioda::Variable v = f.vars.open(varname); // Re-opening to make sure backend persists the params.
43 
44  auto vChunks = v.getChunkSizes();
45  if (chunk) {
46  if (vChunks.size() != dims.size()) {
47  std::cout << "\t\tFailed. Chunk was not set." << std::endl;
48  return false;
49  }
50  for (size_t i = 0; i < vChunks.size(); ++i) {
51  if (vChunks[i] != dims[i]) {
52  std::cout << "\t\tFailed. Chunk size does not match reference." << std::endl;
53  return false;
54  }
55  }
56  } else {
57  if (!vChunks.empty()) {
58  std::cout << "\t\tFailed. Chunk should not be set." << std::endl;
59  return false;
60  }
61  }
62 
63  std::cout << "\t\tSuccess.\n\tCheck compression options." << std::endl;
64 
65  auto vGZIP = v.getGZIPCompression();
66  if (gzip != vGZIP.first) {
67  std::cout << "\t\tFailed. GZIP enable flag does not match reference." << std::endl;
68  return false;
69  }
70  if (gzip && !vGZIP.second) {
71  std::cout << "\t\tFailed. GZIP enabled, but at zero compression level." << std::endl;
72  return false;
73  }
74 
75  auto vSZIP = v.getSZIPCompression();
76  if (szip != std::get<0>(vSZIP)) {
77  std::cout << "\t\tFailed. SZIP enable flag does not match reference." << std::endl;
78  return false;
79  }
80  if (szip) {
81  std::cout << "\t\tSZIP compression was enabled." << std::endl;
82  // TODO(rhoneyager): H5Pset_szip's flags do not match those returned by the HDF5 filter!
83  // These should be decoded and checked in the future.
84  }
85 
86  std::cout << "\t\tSuccess." << std::endl;
87 
88  return true;
89  } catch (...) {
90  std::cout << "\t\tFailed with exception." << std::endl;
91  return false;
92  }
93 }
94 
95 int main(int argc, char **argv) {
96  using namespace ioda;
97  using namespace std;
98  try {
99  auto f = Engines::constructFromCmdLine(argc, argv, "test-filters.hdf5");
100 
101  // These tests try to read and write fill values.
102  // We try basic numbers, fixed-length strings and variable-length
103  // strings.
104  int good = 0, bad = 0;
105 
106  (testVar<std::string>(f, "varlen-string-test", {"This is a test"}, {1}, false, false, false)) ? good++
107  : bad++;
108  (testVar<int>(f, "int-test-nochunks", {1, 2, 3, 4}, {2, 2}, false, false, false)) ? good++ : bad++;
109  (testVar<int>(f, "int-test-chunks", {2, 3, 4, 5}, {2, 2}, true, false, false)) ? good++ : bad++;
110  (testVar<int>(f, "int-test-chunks-gzip", {1, -4, 9, -16}, {2, 2}, true, true, false)) ? good++ : bad++;
111  // Only run if the engine will not fail on SZIP compression.
112  if (f.getCapabilities().canCompressWithSZIP != ioda::Engines::Capability_Mask::Unsupported)
113  (testVar<int>(f, "int-test-chunks-szip", {9, 4, 3, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, {4, 4},
114  true, false, true))
115  ? good++
116  : bad++;
117  else
118  std::cout << "\tSkipping SZIP checks since the backend disables them." << std::endl;
119 
120  std::cout << "\n\nSuccesses: " << good << "\nFailures: " << bad << std::endl;
121  return (bad) ? 1 : 0;
122  } catch (const std::exception &e) {
124  return 1;
125  }
126 }
Structs that describe backend capabilities.
IODA's error system.
Definitions for setting up backends with file and memory I/O.
Interfaces for ioda::Group and related classes.
Groups are a new implementation of ObsSpaces.
Definition: Group.h:159
virtual std::vector< Dimensions_t > getChunkSizes() const
Retrieve the chunking options for the Variable.
Definition: Variable.cpp:123
virtual std::pair< bool, int > getGZIPCompression() const
Retrieve the GZIP compression options for the Variable.
Definition: Variable.cpp:136
virtual std::tuple< bool, unsigned, unsigned > getSZIPCompression() const
Retrieve the SZIP compression options for the Variable.
Definition: Variable.cpp:148
virtual Variable write(gsl::span< char > data, const Type &in_memory_dataType, const Selection &mem_selection=Selection::all, const Selection &file_selection=Selection::all)
The fundamental write function. Backends overload this function to implement all write operations.
Definition: Variable.cpp:317
IODA_DL Group constructFromCmdLine(int argc, char **argv, const std::string &defaultFilename)
This is a wrapper function around the constructBackend function for creating a backend based on comma...
Definition: Factory.cpp:21
@ Unsupported
The feature causes an exception if used.
int main(int argc, char **argv)
bool testVar(ioda::Group &f, const std::string &varname, const std::vector< T > &data, const std::vector< ioda::Dimensions_t > &dims, bool chunk, bool gzip, bool szip)
IODA_DL void unwind_exception_stack(const std::exception &e, std::ostream &out=std::cerr, int level=0)
Convenience function for unwinding an exception stack.
Definition: Exception.cpp:48
Definition: encode.cc:30
Used to specify Variable creation-time properties.
Definition: Has_Variables.h:57