Skip to content

Introduction to static strides and static extents for static Tensor

amitsingh19975 edited this page Jun 22, 2019 · 22 revisions

Abstract

Introduction to static strides and static extents is one step closer to making static Tensor which will make Tensor more efficient.

First Cem Bassoy and I decided to integrate kokkos mdspan but the problem with this implementation is that it is made with keeping array in mind so it was very difficult to integrate with Tensor. To get rid of the problems I implemented the whole static strides and static extents from ground up for keeping tensor in mind.

New To Tensor

  1. extents_helper

It is in detail namespace of ublas and it is an engine for static extents as it has all the logic. It decides how to create the extents with the given parameter pack

Specification for extents_helper

template <ptrdiff_t R, class S> 
struct basic_extents_impl{

  static constexpr ptrdiff_t Rank = 0;

  static constexpr ptrdiff_t DynamicRank;

  static constexpr bool IsDynamic;

  static constexpr ptrdiff_t N; //For static extent
  //        OR
  ptrdiff_t N; // For dynamic extent

  constexpr auto at(int) const noexcept;

  constexpr auto operator[](int) const noexcept;

  constexpr auto product(int) const noexcept;

  constexpr auto product() const noexcept;

  constexpr auto empty() const noexcept;

  constexpr auto size() const noexcept;

  template <typename IndexType, typename... Args>
  constexpr bool in_bounds(IndexType const &idx, Args... args) const noexcept;

  constexpr bool in_bounds() const noexcept;

  constexpr basic_extents_impl();
  constexpr basic_extents_impl(basic_extents_impl const &other);
  constexpr basic_extents_impl& operator=(basic_extents_impl const &other);

  template <typename IndexType>
  explicit constexpr basic_extents_impl(std::initializer_list<IndexType> li);

  template <typename Iterator>
  constexpr basic_extents_impl(Iterator, Iterator,iterator_tag);

  template <typename Iterator>
  basic_extents_impl(Iterator, Iterator, invalid_iterator_tag);

  ~basic_extents_impl() = default;

};
  1. static_extents

It helps you to create extents at compile and runtime as you can create whole extents at compile time or create extents at runtime or mix of both but with compile time rank so you cannot change the rank afterwards if you want dynamic rank then choose basic_extents.

Specification for static_extents

template<classT, ptrdiff_t R, ptrdiff_t ...E>
struct static_extents{
  using base_type = std::vector<int_type>;
  using value_type = typename base_type::value_type;
  using const_reference = typename base_type::const_reference;
  using reference = typename base_type::reference;
  using const_pointer = typename base_type::const_pointer;
  using const_iterator = typename base_type::const_iterator;
  using size_type = std::size_t;

  template <class Extents, class Layout> 
  friend struct static_strides;

  static constexpr auto size() noexcept;
  static constexpr auto rank() noexcept;

  static constexpr auto dynamic_rank() noexcept;

  constexpr auto at(size_type k) const;

  constexpr auto product(size_type k) const noexcept;

  constexpr auto product() const noexcept;

  constexpr static_extents();

  constexpr static_extents(static_extents const &other);

  constexpr static_extents &operator=(static_extents const &other);

  constexpr void set_dynamic_N(static_extents const& e);

  template <class... IndexType>
  constexpr static_extents(IndexType... DynamicExtents);

  constexpr static_extents(base_type const& b);

  template <class I, std::enable_if_t<detail::is_iterator<I>::value, int> = 0>
  constexpr static_extents(I begin, I end);

  constexpr bool is_scalar() const noexcept;

  constexpr bool is_vector() const noexcept;

  constexpr bool is_matrix() const noexcept;

  constexpr bool is_tensor() const noexcept;

  auto to_vector() const;

  auto base() const;

  constexpr auto to_array() const;

  auto to_dynamic_extents() const;

  constexpr auto empty() const noexcept;

  constexpr bool valid() const noexcept;

  template <ptrdiff_t rhs_dims, ptrdiff_t... rhs>
  constexpr auto operator==(static_extents<int_type,rhs_dims, rhs...> const &other) const;

  template <ptrdiff_t rhs_dims, ptrdiff_t... rhs>
  constexpr auto operator!=(static_extents<int_type,rhs_dims, rhs...> const &other) const;

  auto squeeze() const noexcept;

  ~static_extents();

private:
  using impl = detail::basic_extents_impl<0, detail::make_basic_shape_t<R, E...>>;
}

template<ptrdiff_t R, ptrdiff_t... E>
using shape; // selects if you want to use basic_extents or static_extents 
  1. static_strides

It helps you to create strides at compile using static_extents

Specification for static_strides

template <class ExtentType, class Layout> 
struct static_strides{

  using extents_type = static_extents<T, R, Extents...>;
  using base_type = std::vector<T>;
  using layout_type = last_order;
  using value_type = typename base_type::value_type;
  using reference = typename base_type::reference;
  using const_reference = typename base_type::const_reference;
  using size_type = typename base_type::size_type;
  using const_pointer = typename base_type::const_pointer;
  using const_iterator = typename base_type::const_iterator;

  constexpr auto at(int k) const ;

  constexpr auto operator[](int k) const;

  constexpr auto rank() const noexcept;

  constexpr auto size() const noexcept;

  constexpr auto extent(int k) const noexcept;

  constexpr auto product(int k) const noexcept;

  constexpr static_strides() noexcept;

  constexpr static_strides(extents_type const &e) noexcept;


  constexpr static_strides(static_strides const &other) noexcept;

  constexpr static_strides & operator=(static_strides const &other) noexcept;

  template <class... IndexType>
  explicit constexpr static_strides(value_type extent,IndexType... DynamicExtents) noexcept;

  template <class Iterator, class = class std::enable_if<std::is_same<
                                detail::iterator_tag_t<Iterator>,
                                class detail::iterator_tag>::value>::type>
  constexpr static_strides(Iterator begin, Iterator end, detail::iterator_tag) noexcept;

  constexpr auto stride(int k) const;

  auto base() const;

private:
  template <class E>
  static constexpr auto access(E const &, value_type sum) noexcept;

  template <class E, class... IndexType>
  static constexpr auto access(E const &e, value_type sum, value_type i_el,
                               IndexType const &... idxs) noexcept;

  using impl = typename extents_type::impl;

};

template <class E, class Layout> 
struct stride_type; // selects if you want to use basic_strides or static_strides 

Updated tensor class

/**
* ....
* @tparam E type of basic_extents or static_extents defaults to shape<dynamic_rank>
* ....
*/
template<class T, class E, class F, class A>
class tensor;

Examples

auto t1 = tensor<int>{}; // tensor with dynamic extents and dynamic strides
auto t2 = tensor<int,shape<4>>{1,2,3,4}; // tensor with static rank but dynamic extents and static_strides
auto t3 = tensor<int,shape<4,1,dynamic_extent,dynamic_extent,4>>{2,3}; // tensor with static rank, mix of dynamic extents and static extents and static strides
auto t3 = tensor<int,shape<4,1,2,3,4>>{}; // tensor with static_rank, static extents and static_strides
Clone this wiki locally