Skip to content

File sessionguard.h

File List > code_source > templat > include > TempLat > session > sessionguard.h

Go to the documentation of this file

#ifndef TEMPLAT_SESSION_SESSIONGUARD_H
#define TEMPLAT_SESSION_SESSIONGUARD_H

/* This file is part of TempLat, available at https://cosmolattice.github.io/templat .
   Copyright 2021-2026 The TempLat authors, see AUTHORS.md.
   Released under the MIT license, see LICENSE.md. */

// File info: Main contributor(s): Wessel Valkenburg, Year: 2019

#include "TempLat/fft/fftlibraryselector.h"
#include "TempLat/parallel/device_guard.h"
#include "TempLat/parallel/mpi/session/mpiguard.h"
#include "TempLat/util/exception.h"

namespace TempLat
{
  MakeException(SessionGuardInstantiationException);

  class SessionGuard
  {
  public:
    // Put public methods here. These should change very little over time.
    SessionGuard(int argc, char *argv[], bool verbose = false)
        : instanceProtectionKey(InstanceCounter(1)), mMPIGuard(argc, argv, verbose), mDeviceGuard(argc, argv, verbose),
          mFFTSessionGuards(getFFTSessionGuards(verbose))
    {
    }

    // Getter for testing purposes only. Allows tests to check the current instance counter.
    static inline int GetInstanceCounter() { return InstanceCounter(); }

  private:
    /* Put all member variables and private methods here. These may change arbitrarily. */
    int instanceProtectionKey;
    MPIGuard mMPIGuard;
    DeviceGuard mDeviceGuard;
    std::vector<std::shared_ptr<FFTSessionGuard>> mFFTSessionGuards;

    static inline int InstanceCounter(int delta = 0)
    {
      static int counter = 0;
      counter += delta;
      if (counter > 1)
        throw SessionGuardInstantiationException("Per process, the MPIGuard can be instantiated only once. This should "
                                                 "be done in `int main()`. This is wrong. Instances:",
                                                 counter);
      return counter;
    }
  };
} // namespace TempLat

#endif