File std.h
File List > code_source > templat > include > TempLat > parallel > devices > std > std.h
Go to the documentation of this file
#ifndef TEMPLAT_PARALLEL_STD_STD_H
#define TEMPLAT_PARALLEL_STD_STD_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): Franz R. Sattler, Year: 2025
#include "TempLat/util/log/puttostream.h"
#include <ostream>
#include <sys/types.h>
// Including this here, as we need that anywhere basically.
#include "TempLat/lattice/algebra/helpers/isvariadicindex.h"
#include <array>
#include <tuple>
#define DEVICE_FUNCTION
#define DEVICE_FORCEINLINE_FUNCTION inline
#define DEVICE_INLINE_FUNCTION inline
#define DEVICE_LAMBDA [&]
#define DEVICE_CLASS_LAMBDA [&, this ]
namespace TempLat
{
// Need to forward-declare this - we cannot include the layout header here, as it would create a circular
// dependency.
template <size_t NDim> struct LayoutStruct;
namespace std_device
{
// What's going on here: on GPU, it is beneficial to reverse the memory access pattern, for coalesced access.
// However, we do not want to impose this on the level of the memory layouts. In particular, this would
// require additional transpositions when going to Fourier space, which is not what we want. So we do the
// transposition within the thread dispatch, if we are on a GPU. Otherwise, for optimal cached memory access
// on CPU, we do not reverse the access pattern.
#ifdef FORCE_ACCESS_PATTERN
#if FORCE_ACCESS_PATTERN == 0
constexpr bool reverse_access_pattern = false;
#elif FORCE_ACCESS_PATTERN == 1
constexpr bool reverse_access_pattern = true;
#endif
#else
constexpr bool reverse_access_pattern = false;
#endif
// ------------------------------------------------
// Standard library replacements in std_device namespace
// ------------------------------------------------
template <typename... T> using tuple = std::tuple<T...>;
template <typename T, std::size_t N> using array = std::array<T, N>;
using std::apply;
using std::forward_as_tuple;
using std::get;
using std::index_sequence;
using std::make_tuple;
using std::tie;
using std::tuple_cat;
using Idx = int64_t;
template <size_t NDim> using IdxArray = std::array<Idx, NDim>;
// ------------------------------------------------
// View types
// ------------------------------------------------
template <typename T, size_t NDim> class NDView
{
};
template <typename T, size_t NDim> class NDViewUnmanaged
{
};
} // namespace std_device
} // namespace TempLat
template <typename T, typename S>
requires(std::is_same<T, decltype((T)std::declval<S>())>::value &&
!(
requires(std::decay_t<S> s, std::size_t i) { s.eval(i); } ||
requires(std::decay_t<S> s, std::size_t i, std::size_t j) { s.eval(i, j); } ||
requires(std::decay_t<S> s, std::size_t i, std::size_t j, std::size_t k) { s.eval(i, j, k); }))
complex<T> operator*(complex<T> a, S b)
{
return a * (T)b;
}
template <typename T, typename S>
requires(std::is_same<T, decltype((T)std::declval<S>())>::value &&
!(
requires(std::decay_t<S> s, std::size_t i) { s.eval(i); } ||
requires(std::decay_t<S> s, std::size_t i, std::size_t j) { s.eval(i, j); } ||
requires(std::decay_t<S> s, std::size_t i, std::size_t j, std::size_t k) { s.eval(i, j, k); }))
DEVICE_INLINE_FUNCTION complex<T> operator*(S b, complex<T> a)
{
return a * (T)b;
}
#endif