Skip to content

File dimensioncountrecorder.h

File List > algebra > coordinates > dimensioncountrecorder.h

Go to the documentation of this file

#ifndef TEMPLAT_LATTICE_ALGEBRA_COORDINATES_DIMENSIONCOUNTRECORDER_H
#define TEMPLAT_LATTICE_ALGEBRA_COORDINATES_DIMENSIONCOUNTRECORDER_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/lattice/algebra/spacestateinterface.h"
#include "TempLat/parallel/devices/kokkos/kokkos.h"

namespace TempLat
{
  MakeException(DimensionCountRecorderException);
  MakeException(DimensionCountRecorder_CoordinateSpaceException);

  template <size_t NDim> class DimensionCountRecorder
  {
  public:
    // Put public methods here. These should change very little over time.
    DimensionCountRecorder(SpaceStateType spaceType)
        : mFixedSingleSpaceType(spaceType), mCurrentSpaceType(spaceType), mCurrentLayout({}, 0)
    {
    }

    void confirmSpace(const LayoutStruct<NDim> &newLayout, const SpaceStateType &spaceType) const
    {
      if (mFixedSingleSpaceType != SpaceStateType::undefined && mFixedSingleSpaceType != spaceType) {
        // Guard on DEVICE_REGION (actual device-code compilation) rather than DEVICE_KOKKOS: confirmSpace is
        // called from host code during onBeforeAssignment, so the throw must survive on the host in a Kokkos
        // build and be dropped only inside device kernels, where `throw` is illegal.
#ifndef DEVICE_REGION
        throw DimensionCountRecorder_CoordinateSpaceException(
            "You are using coordinates in one space for an expression in another space. This coordinate object insists "
            "on",
            SpaceStateInterface<NDim>::SpaceTypeString(mFixedSingleSpaceType), "while you now ask for",
            SpaceStateInterface<NDim>::SpaceTypeString(spaceType));
#endif
      }

      mCurrentSpaceType = spaceType;
      mCurrentLayout = newLayout;
    }

    static constexpr device::Idx getNDimensions() { return NDim; }
    SpaceStateType getCurrentSpaceType() const { return mCurrentSpaceType; }
    DEVICE_FORCEINLINE_FUNCTION
    const LayoutStruct<NDim> &getCurrentLayout() const { return mCurrentLayout; }

    std::string toString() const
    {
      return SpaceStateInterface<NDim>::SpaceTypetoCanonicalCharacter(mFixedSingleSpaceType);
    }

  private:
    /* Put all member variables and private methods here. These may change arbitrarily. */
    mutable SpaceStateType mFixedSingleSpaceType;
    mutable SpaceStateType mCurrentSpaceType;
    mutable LayoutStruct<NDim> mCurrentLayout;
  };
} // namespace TempLat

#endif