SpECTRE Documentation Coverage Report
Current view: top level - Parallel - ArrayIndex.hpp Hit Total Coverage
Commit: 35a1e98cd3e4fdea528eb8100f99c2f707894fda Lines: 1 17 5.9 %
Date: 2024-04-19 00:10:48
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #pragma once
       5             : 
       6             : #include <charm++.h>
       7             : #include <type_traits>
       8             : 
       9             : #include "Utilities/ErrorHandling/Assert.hpp"
      10             : #include "Utilities/TypeTraits/IsA.hpp"
      11             : 
      12             : namespace Parallel {
      13             : /*!
      14             :  * \ingroup ParallelGroup
      15             :  * \brief The array index used for indexing Chare Arrays, mostly an
      16             :  * implementation detail
      17             :  *
      18             :  * The implementation is generic and can handle custom array indices. This
      19             :  * replaces the generated, hard-coded Charm++ array indices with a template,
      20             :  * allowing a single implementation to be used for different array indices.
      21             :  *
      22             :  * \details Charm++ allocates memory for `CkArrayIndex`. The size can be
      23             :  * configured (in the Charm++ configuration) and defaults to the size of three
      24             :  * integers. We place the `Index` into this buffer using placement `new`. Then,
      25             :  * `CkArrayIndex::data()` can be safely reinterpreted as an `Index*`.
      26             :  */
      27             : template <class Index>
      28           1 : struct ArrayIndex : public CkArrayIndex {
      29             :   static_assert(std::is_standard_layout_v<Index> and std::is_trivial_v<Index>,
      30             :                 "The array index type must be a POD, plain-old-data");
      31             :   // clang-tidy: suspicious use of sizeof
      32             :   static_assert(sizeof(Index) <= 3 * sizeof(int),  // NOLINT
      33             :                 "The default Charm++ CK_ARRAYINDEX_MAXLEN is 3. If you have "
      34             :                 "changed this at Charm++ configuration time then please update "
      35             :                 "the static_assert, otherwise your Index type is too large.");
      36             :   // clang-tidy: suspicious use of sizeof
      37             :   static_assert(sizeof(Index) % sizeof(int) == 0,  // NOLINT
      38             :                 "The Charm++ array Index type must be exactly a multiple of "
      39             :                 "the size of an integer, but the user-provided one is not.");
      40             :   static_assert(
      41             :       alignof(Index) == alignof(decltype(index)),
      42             :       "Incorrect alignment of Charm++ array Index type. The "
      43             :       "alignment must match the alignment of the internal Charm++ type");
      44             :   static_assert(not tt::is_a_v<ArrayIndex, Index>,
      45             :                 "The Index type passed to ArrayIndex cannot be an ArrayIndex");
      46             : 
      47             :   // Use placement new to ensure that the custom index object is placed in the
      48             :   // memory reserved for it in the base class
      49             :   // clang-tidy: mark explicit: it's a conversion constructor
      50           0 :   ArrayIndex(const Index& array_index)  // NOLINT
      51             :                                         // clang-tidy: do not use unions
      52             :       : array_index_(new (index) Index(array_index)) {  // NOLINT
      53             :     // clang-tidy: suspicious use of sizeof
      54             :     nInts = sizeof(array_index) / sizeof(int);  // NOLINT
      55             :   }
      56             : 
      57             :   // clang-tidy: mark explicit: it's a conversion constructor
      58           0 :   ArrayIndex(const CkArrayIndex& array_index)  // NOLINT
      59             :       : CkArrayIndex(array_index),
      60             :         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
      61             :         array_index_(reinterpret_cast<Index*>(CkArrayIndex::data())) {
      62             :     ASSERT(CkArrayIndex::nInts * sizeof(int) == sizeof(Index),
      63             :            "The CkArrayIndex::nInts does not match the size of the custom "
      64             :            "array index class.");
      65             :   }
      66             : 
      67           0 :   ArrayIndex(const ArrayIndex& rhs) = delete;
      68           0 :   ArrayIndex& operator=(const ArrayIndex& rhs) = delete;
      69             : 
      70           0 :   ArrayIndex(ArrayIndex&& /*rhs*/) = delete;
      71           0 :   ArrayIndex& operator=(ArrayIndex&& /*rhs*/) = delete;
      72           0 :   ~ArrayIndex() = default;
      73             : 
      74           0 :   const Index& get_index() const { return *array_index_; }
      75             : 
      76             :  private:
      77           0 :   Index* array_index_ = nullptr;
      78             : };
      79             : 
      80           0 : using ArrayIndex1D = ArrayIndex<CkIndex1D>;
      81           0 : using ArrayIndex2D = ArrayIndex<CkIndex2D>;
      82           0 : using ArrayIndex3D = ArrayIndex<CkIndex3D>;
      83           0 : using ArrayIndex4D = ArrayIndex<CkIndex4D>;
      84           0 : using ArrayIndex5D = ArrayIndex<CkIndex5D>;
      85           0 : using ArrayIndex6D = ArrayIndex<CkIndex6D>;
      86             : }  // namespace Parallel
      87             : 
      88             : // These namespaces have silly names because we are subverting the charm++
      89             : // utilities that prepend "CkArrayIndex" to the name of the array index. See
      90             : // comments in Parallel/Algorithms/AlgorithmArray.ci for further explanation.
      91             : 
      92             : namespace CkArrayIndexSpectreIndex_detail {
      93             : template <typename Index>
      94             : using ArrayIndex = ::Parallel::ArrayIndex<Index>;
      95             : }  // namespace CkArrayIndexSpectreIndex_detail
      96             : 
      97             : namespace SpectreIndex_detail {
      98             : template <typename Index>
      99             : using ArrayIndex = Index;
     100             : }  // namespace SpectreIndex_detail

Generated by: LCOV version 1.14