• Docs >
  • Program Listing for File block_traits.hpp
Shortcuts

Program Listing for File block_traits.hpp

Return to documentation for file (include/ripple/container/block_traits.hpp)

#ifndef RIPPLE_CONTAINER_BLOCK_TRAITS_HPP
#define RIPPLE_CONTAINER_BLOCK_TRAITS_HPP

#include <ripple/iterator/block_iterator.hpp>
#include <ripple/space/dynamic_multidim_space.hpp>
#include <ripple/storage/storage_traits.hpp>
#include <ripple/utility/portability.hpp>

namespace ripple {

/*==--- [forward declarations] ---------------------------------------------==*/

template <typename T, size_t Dimensions>
class DeviceBlock;

template <typename T, size_t Dimensions>
class HostBlock;

template <typename T, size_t Dimensions>
struct Block;

/*==--- [block traits] -----------------------------------------------------==*/

enum class BlockOpKind : uint8_t {
  asynchronous = 0,
  synchronous  = 1
};

template <typename T>
struct BlockTraits {
  // clang-format off
  using Value     = void*;
  using Allocator = void*;
  using Space     = void*;
  using Iter      = BlockIterator<Value, Space>;

  static constexpr auto dimensions      = 0;
  static constexpr auto is_block        = false;
  static constexpr auto is_host_block   = false;
  static constexpr auto is_device_block = false;
  // clang-format on
};

template <typename T, size_t Dimensions>
struct BlockTraits<HostBlock<T, Dimensions>> {
 private:
  using LayoutTraits = layout_traits_t<T>;

 public:
  // clang-format off
  using Value     = typename LayoutTraits::Value;
  using Allocator = typename LayoutTraits::Allocator;
  using Space     = DynamicMultidimSpace<Dimensions>;
  using Iter      = BlockIterator<Value, Space>;

  static constexpr size_t dimensions      = Dimensions;
  static constexpr bool   is_block        = true;
  static constexpr bool   is_host_block   = true;
  static constexpr bool   is_device_block = false;
  static constexpr size_t alignment       = LayoutTraits::alignment;
  // clang-format on
};

template <typename T, size_t Dimensions>
struct BlockTraits<DeviceBlock<T, Dimensions>> {
 private:
  using LayoutTraits = layout_traits_t<T>;

 public:
  // clang-format off
  using Value     = typename LayoutTraits::Value;
  using Allocator = typename LayoutTraits::Allocator;
  using Space     = DynamicMultidimSpace<Dimensions>;
  using Iter      = BlockIterator<Value, Space>;

  static constexpr size_t dimensions      = Dimensions;
  static constexpr bool   is_block        = true;
  static constexpr bool   is_host_block   = false;
  static constexpr bool   is_device_block = true;
  static constexpr size_t alignment       = LayoutTraits::alignment;
  // clang-format on
};

template <typename T>
struct MultiBlockTraits {
  // clang-format off
  using Value      = void*;
  using Iterator   = void*;

  static constexpr size_t dimensions = 0;
  // clang-format on
};

template <typename T>
struct AnyBlockTraits {
 private:
  // clang-format off
  using Traits = std::conditional_t<
    BlockTraits<T>::is_block, BlockTraits<T>, MultiBlockTraits<T>>;
  // clang-format on

 public:
  using Value = typename Traits::Value;

  static constexpr size_t dimensions = Traits::dimensions;
};

/*==--- [multi block] ------------------------------------------------------==*/

template <typename Impl>
struct MultiBlock {
  auto impl() const noexcept -> const Impl* {
    return static_cast<const Impl*>(this);
  }

  auto impl() noexcept -> Impl* {
    return static_cast<Impl*>(this);
  }

 public:
  auto device_iterator() noexcept -> typename MultiBlockTraits<Impl>::Iterator {
    return impl()->device_iterator();
  }

  auto host_iterator() noexcept -> typename MultiBlockTraits<Impl>::Iterator {
    return impl()->host_iterator();
  }

  decltype(auto) stream() const noexcept {
    return impl()->stream();
  }

  template <typename Dim>
  auto size(Dim&& dim) const noexcept -> size_t {
    return impl()->size(ripple_forward(dim));
  }
};

/*==--- [aliases] ----------------------------------------------------------==*/

template <typename T>
using multiblock_traits_t = MultiBlockTraits<std::decay_t<T>>;

template <typename T>
using block_traits_t = BlockTraits<std::decay_t<T>>;

template <typename T>
using any_block_traits_t = AnyBlockTraits<std::decay_t<T>>;

template <typename T>
using HostBlock1d = HostBlock<T, 1>;

template <typename T>
using DeviceBlock1d = DeviceBlock<T, 1>;

template <typename T>
using HostBlock2d = HostBlock<T, 2>;

template <typename T>
using DeviceBlock2d = DeviceBlock<T, 2>;

template <typename T>
using HostBlock3d = HostBlock<T, 3>;

template <typename T>
using DeviceBlock3d = DeviceBlock<T, 3>;

/*==--- [traits] -----------------------------------------------------------==*/

template <typename T>
static constexpr auto is_block_v = block_traits_t<T>::is_block;

template <typename T>
static constexpr auto is_host_block_v = block_traits_t<T>::is_host_block;

template <typename T>
static constexpr auto is_device_block_v = block_traits_t<T>::is_device_block;

template <typename T>
static constexpr bool is_multiblock_v =
  std::is_base_of_v<MultiBlock<std::decay_t<T>>, std::decay_t<T>>;

template <typename T>
static constexpr bool is_any_block_v = is_block_v<T> || is_multiblock_v<T>;

template <typename T>
using block_enable_t = std::enable_if_t<is_block_v<T>, int>;

template <typename T>
using non_block_enable_t = std::enable_if_t<!is_block_v<T>, int>;

template <typename T>
using multiblock_enable_t = std::enable_if_t<is_multiblock_v<T>, int>;

template <typename T>
using non_multiblock_enable_t = std::enable_if_t<!is_multiblock_v<T>, int>;

template <typename T>
using any_block_enable_t =
  std::enable_if_t<is_multiblock_v<T> || is_block_v<T>, int>;

template <typename T>
using non_any_block_enable_t =
  std::enable_if_t<!is_multiblock_v<T> && !is_block_v<T>, int>;

template <typename T>
using block_1d_enable_t =
  std::enable_if_t<is_block_v<T> && block_traits_t<T>::dimensions == 1, int>;

template <typename T>
using block_2d_enable_t =
  std::enable_if_t<is_block_v<T> && block_traits_t<T>::dimensions == 2, int>;

template <typename T>
using block_3d_enable_t =
  std::enable_if_t<is_block_v<T> && block_traits_t<T>::dimensions == 3, int>;

template <typename T>
using any_block_1d_enable_t = std::enable_if_t<
  (is_block_v<T> && block_traits_t<T>::dimensions == 1) ||
    (is_multiblock_v<T> && multiblock_traits_t<T>::dimensions == 1),
  int>;

template <typename T>
using any_block_2d_enable_t = std::enable_if_t<
  (is_block_v<T> && block_traits_t<T>::dimensions == 2) ||
    (is_multiblock_v<T> && multiblock_traits_t<T>::dimensions == 2),
  int>;

template <typename T>
using any_block_3d_enable_t = std::enable_if_t<
  (is_block_v<T> && block_traits_t<T>::dimensions == 3) ||
    (is_multiblock_v<T> && multiblock_traits_t<T>::dimensions == 3),
  int>;

} // namespace ripple

#endif // RIPPLE_CONTAINER_BLOCK_TRAITS_HPP

Docs

Access comprehensive developer documentation for Ripple

View Docs

Tutorials

Get tutorials to help with understand all features

View Tutorials

Examples

Find examples to help get started

View Examples