text: #include <string>
  #include <vector>
  
  #include "eckit/log/Bytes.h"
  #include "eckit/log/ResourceUsage.h"
  #include "eckit/system/ResourceUsage.h"
  
  #include "atlas/domain.h"
  #include "atlas/grid.h"
  #include "atlas/runtime/Trace.h"
  #include "atlas/runtime/trace/StopWatch.h"
  #include "tests/AtlasTestEnvironment.h"
  
  namespace atlas {
  namespace test {
  
  // Computation of gaussian latitudes for large grids can be quite costly in terms of
  // time and memory.
  // Atlas has a number of commonly used resolutions precomputed which can speed up Gaussian grids
  // and prevents large peaks in memory usage. See gaussian Spacing.
  //
  // If more high resolution Gaussian latitudes need to be precomputed they can be added there, or in
  // a dynamic library with self-registration.
  
  struct Trace {
      struct Indentor {
          Indentor() { Log::info().indent(); }
          ~Indentor() { Log::info().unindent(); }
      } indentor;
      eckit::ResourceUsage resource_usage;
      atlas::Trace trace;
  
      Trace(const eckit::CodeLocation& where, const std::string& what):
          indentor{}, resource_usage{what, Log::debug()}, trace{where, what} {}
  
      double elapsed() const { return trace.elapsed(); }
      static size_t peakMemory() { return eckit::system::ResourceUsage().maxResidentSetSize(); }
      void stopAndReport() {
          trace.stop();
          Log::info() << "Time taken:        " << elapsed() << " sec" << std::endl;
          Log::info() << "Peak memory usage: " << eckit::Bytes(peakMemory()) << std::endl;
      }
  };
  
  constexpr size_t Mbytes = 1000000;
  
  CASE("test resources for cropping large grids") {
      std::vector<std::string> gridnames{"L40000x20000", "N8000", "O8000"};
  
      for (auto& gridname : gridnames) {
          EXPECT(Trace::peakMemory() < 100 * Mbytes);
  
          SECTION(std::string("section") + gridname) {
              Trace trace(Here(), "Grid{" + gridname + ", GlobalDomain{-180}}");
              auto grid = Grid{gridname, GlobalDomain{-180}};
              trace.stopAndReport();
              EXPECT(trace.elapsed() < 10.);
              EXPECT(trace.peakMemory() < 100 * Mbytes);
          }
      }
  }
  
  
  }  // namespace test
  }  // namespace atlas
  
  
  int main(int argc, char* argv[]) {
      return atlas::test::run(argc, argv);
  }
  