Skip to content

Instantly share code, notes, and snippets.

@amitsingh19975
Last active May 31, 2019 16:30
Show Gist options
  • Save amitsingh19975/7509505b6979cecba4c65a62d95f7449 to your computer and use it in GitHub Desktop.
Save amitsingh19975/7509505b6979cecba4c65a62d95f7449 to your computer and use it in GitHub Desktop.
#include <boost/numeric/ublas/functional.hpp>
#include <boost/numeric/ublas/tensor/extents.hpp>
#include <boost/numeric/ublas/tensor/extents_helper.hpp>
#include <boost/numeric/ublas/tensor/strides.hpp>
#include <complex>
#include <iostream>
#include <type_traits>
namespace boost::numeric::ublas {
using first_order = column_major;
using last_order = row_major;
} // namespace boost::numeric::ublas
namespace boost::numeric::ublas::detail {
template <class E, class __layout> struct basic_extent_layout;
template <class S>
struct basic_extent_layout<basic_extents_impl<0, S>, last_order>
: basic_extents_impl<0, S> {
static_assert(is_basic_shape_v<S>, "Not a basic shape");
using impl = basic_extents_impl<0, S>;
using index_type = ptrdiff_t;
constexpr auto at(int k) const noexcept { return impl::at(k); }
constexpr auto rank() const noexcept { return impl::Rank; }
constexpr auto product(int k) const noexcept { return impl::product(k); }
constexpr auto stride(int k) const noexcept {
return impl::next::product(k + 1);
}
constexpr basic_extent_layout() noexcept = default;
constexpr basic_extent_layout(basic_extent_layout const &other) noexcept =
default;
constexpr basic_extent_layout &
operator=(basic_extent_layout const &other) noexcept = default;
template <typename... IndexType>
explicit constexpr basic_extent_layout(ptrdiff_t extent,
IndexType... DynamicExtents) noexcept
: impl(extent, DynamicExtents...) {}
template <typename Iterator>
constexpr basic_extent_layout(Iterator begin, Iterator end,
iterator_tag) noexcept
: impl(begin, end, iterator_tag{}) {}
private:
template <class E>
static constexpr auto access(E const &, index_type sum) noexcept {
return sum;
}
template <class E, class... IndexType>
static constexpr auto access(E const &e, index_type sum, index_type i_el,
IndexType const &... idxs) noexcept {
return basic_extent_layout::access((typename E::next const &)e,
sum * e.N + i_el, idxs...);
}
public:
constexpr auto operator()() const noexcept { return 0; }
template <class... IndexType>
constexpr auto operator()(IndexType const &... idxs) const noexcept {
return basic_extent_layout::access((typename impl::next const &)*this,
idxs...);
}
};
template <class S>
struct basic_extent_layout<basic_extents_impl<0, S>, first_order>
: basic_extents_impl<0, S> {
static_assert(is_basic_shape_v<S>, "Not a basic shape");
using impl = basic_extents_impl<0, S>;
using index_type = ptrdiff_t;
constexpr auto at(int k) const noexcept { return impl::at(k); }
constexpr auto rank() const noexcept { return impl::Rank; }
constexpr auto product(int k) const noexcept { return impl::product(k); }
constexpr basic_extent_layout() noexcept = default;
constexpr basic_extent_layout(basic_extent_layout const &other) noexcept =
default;
constexpr basic_extent_layout &
operator=(basic_extent_layout const &other) noexcept = default;
template <typename... IndexType>
explicit constexpr basic_extent_layout(ptrdiff_t extent,
IndexType... DynamicExtents) noexcept
: impl(extent, DynamicExtents...) {}
template <typename Iterator>
constexpr basic_extent_layout(Iterator begin, Iterator end,
iterator_tag) noexcept
: impl(begin, end, iterator_tag{}) {}
private:
template <class E>
static constexpr index_type stride(E const &e, index_type k) noexcept {
return k ? (e.N * stride((typename E::next const &)e, k - 1)) : index_type{1};
}
template <class E> static constexpr auto access(E const &) noexcept {
return 0;
}
template <class E, class... IndexType>
static constexpr auto access(E const &e, index_type i_el,
IndexType const &... idxs) noexcept {
return i_el + e.N * basic_extent_layout::access((typename E::next const &)e,
idxs...);
}
public:
constexpr auto stride(index_type k) const noexcept {
return stride((impl const &)*this, k);
}
constexpr auto operator()() const noexcept { return 0; }
template <class... IndexType>
constexpr auto operator()(IndexType const &... idxs) const noexcept {
return basic_extent_layout::access((impl const &)*this, idxs...);
}
};
template<ptrdiff_t R, ptrdiff_t... E>
using extents = boost::numeric::ublas::detail::basic_extents_impl<0,boost::numeric::ublas::detail::make_basic_shape_t<R,E...>>;
int main(int argc, char const *argv[]) {
using e = extents<5,2,3,tensor::dynamic_extent,tensor::dynamic_extent,1>;
using first_order_lay = tensor::detail::basic_extent_layout<e,tensor::first_order>;
using last_order_lay = tensor::detail::basic_extent_layout<e,tensor::last_order>;
first_order_lay f(3,4);
last_order_lay l(3,5);
for(auto i = 0; i < f.size(); i++){
cout<<f.stride(i)<<'\n'; //1 2 6 18 72
}
for(auto i = 0; i < f.size(); i++){
cout<<l.stride(i)<<'\n'; //45 15 5 1 1
}
cout<<f(1,3,4)<<'\n';
return 0;
}
@bassoy
Copy link

bassoy commented May 31, 2019

Could you also provide the implementation of basic_extents_impl<0, S>;?

@bassoy
Copy link

bassoy commented May 31, 2019

Could you please rename the file to stride.cpp so there is highlighting?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment