-
Notifications
You must be signed in to change notification settings - Fork 5
Introduction to static strides and static extents for static Tensor
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.
Problems with Kokkos midspan
- You cannot create extents with specific size but you have to provide extents which made the construction of
static rank but dynamic extents impossible.
i.e
extents<2,3,4,5>
,extents<2,dynamic_extent,4,5>
extents<5>
extents of size 5 is not possible
-
Few unnecessary functions and data members related to arrays or not related to tensor. i.e
static_extent(int)
,struct mdspan_prop
, etc -
Unnecessary code which was not related to tensor such as props, etc. i.e
struct slices_impl
,struct mdspan_prop
, etc
How I mitigated the Problems
- Problem related to static rank and dynamic extents, I created shape_helper similar to
std::index_sequence
which creates the sequence and fills the repeated sequence of -1 with specific size intobasic_extents_impl
, so now it's possible to specify size at compile time.
i.e
auto s1 = make_basic_shape_t<5>{};// basic_shape<-1,-1,-1,-1,-1>
auto s2 = make_basic_shape_t<3,1,2,3>{};// basic_shape<1,2,3>
-
Second problem was easily mitigated as I removed the unused methods and data members
-
For third problem I chose only
extents_impl
,layout_right
andlayout_left
but modified them according to the needs of tensor
basic_extents_impl
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
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;
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;
};
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
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 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);
auto to_vector() const;
auto base() const;
constexpr auto to_array() const;
auto to_dynamic_extents() const;
constexpr auto empty() 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;
~static_extents();
private:
using impl = detail::basic_extents_impl<0, detail::make_basic_shape_t<R, E...>>;
}
- Different Types of Extents
-
static_extents</*extents*/>
=> static rank and static extents -
dynamic_extents</*Rank*/>
=> static rank and dynamic extents -
dynamic_extents<>
=> dynamic rank and dynamic extents
-
static_strides
It helps you to create strides at compile using static_extents
Specification
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
/**
* ....
* @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;
auto t1 = tensor<int>{}; // tensor with dynamic extents and dynamic strides
auto t2 = tensor<int,dynamic_extents<4>>{dynamic_shape<4>{1,2,3,4}}; // tensor with static rank but dynamic extents and static_strides
auto t3 = tensor{dynamic_extents<4>{1,2,3,4},4}; //same as above but with deduction guide
auto t4 = tensor<int,static_extents<1,2,3,4>>{}; // tensor with static rank, static extents and static strides
auto t5 = tensor{shape<4,1,2,3,4>{)}; // if you don't pass second parameter the type will be of float and also using deduction guide
We both would like to thank our mentor Cem for his constant support and help in achieving our goals. We always find him helpful and he was always easy to reach for help or discussion regarding the work. We would also like to thank Google for the Google Summer of Code Programme, without which all these wouldn't be possible. Lastly, we express our gratitude to our parents for helping and providing us with all the indirect or direct needs for carrying out our work nicely in our homes.
- Home
- Project Proposal
- Milestones and Tasks
- Implementation
- Documentation
- Discussions
- Examples
- Experimental features
- Project Proposal
- Milestones and Tasks
- Implementation
- Documentation
- Discussions
- Example Code