-
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.
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;
};
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
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
/**
* ....
* @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,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
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