FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

np.tile implementation issues · Issue #1821 · xtensor-stack/xtensor · GitHub

Repository navigation

np.tile implementation issues #1821

Closed

Description

I'm trying to partially implement np.roll with xt::pad in reflection mode. Here's my code:

template<class Expr>
inline void tile(xt::xexpression<Expr> &data_expr, std::vector<size_t> ns){
	Expr &data = data_expr.derived_cast();
	std::vector<std::vector<size_t>> tile_vec;
	size_t counter=0;
	for(const auto &val:ns){
		std::vector<size_t> v(2);
		v[0] = 0;
		v[1] = val*data.shape()[counter++];
		tile_vec.emplace_back(std::move(v));
	}
	data = xt::pad(data, tile_vec, xt::pad_mode::reflect);
}

desired behavior:

auto a = xt::arange<int>(2); // a = {0,1}
std::vector<size_t> tile_vec = {1};
tile(a, tile_vec); // a = {0,1,0,1}

but that won't compile. error:

In file included from tile_test.cpp:3:0:
/usr/include/xtensor/xpad.hpp: In instantiation of ‘auto xt::pad(E&&, const std::vector<std::vector<R, std::allocator<_Tp> > >&, xt::pad_mode, V) [with E = xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >&; S = long unsigned int; V = int]’:
tile_test.cpp:17:16:   required from ‘void tile(xt::xexpression<D>&, std::vector<long unsigned int, std::allocator<long unsigned int> >) [with Expr = xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >]’
tile_test.cpp:23:18:   required from here
/usr/include/xtensor/xpad.hpp: 100:21: error: no match for ‘operator=’ (operand types are ‘xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >’ and ‘xt::xgenerator<xt::detail::concatenate_impl<const xt::xfunction<xt::detail::multiplies, xt::xscalar<const int&>, xt::xbroadcast<xt::xscalar<int>, std::array<long unsigned int, 1> > >&, const xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >&, const xt::xfunction<xt::detail::multiplies, xt::xscalar<const int&>, xt::xbroadcast<xt::xscalar<int>, std::array<long unsigned int, 1> > >&>, int, std::array<long unsigned int, 1> >’)
                 out = xt::concatenate(xt::xtuple(bgn, out, end), axis);
                 ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/xtensor/xbuilder.hpp:34:0,
                 from /usr/include/xtensor/xreducer.hpp:29,
                 from /usr/include/xtensor/xmath.hpp:28,
                 from /usr/include/xtensor/xcontainer.hpp:24,
                 from /usr/include/xtensor/xarray.hpp:20,
                 from tile_test.cpp:1:
/usr/include/xtensor/xgenerator.hpp:91:11: note: candidate: xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >& xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >::operator=(const xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >&)
     class xgenerator : public xsharable_expression<xgenerator<F, R, S>>,

what am I doing wrong?

Activity

  1. tdegeus commented on Nov 27, 2019

    Member

    In terms of your problem, could you try with

    xt::xtensor<int,1> a = xt::arange<int>(2);

    forcing the generator to be evaluated resulting in a real array?

    Then, it would be really great to have xt::tile and xt::roll as well! Would you be willing to convert your efforts in one or two PRs?

    As to the xt::roll, my intuition would be that it would be best to do it with minimal allocation. xt::pad has to allocate the full bigger matrix. In contrast, xt::roll could potentially get away with minimal temporary storage. Though you or others may have a different intuition.

  2. tort-dla-psa commented on Nov 27, 2019

    Author

    It kinda works with real xarray/xtensor passing, but I have some strange results:

    template<class Expr>
    inline void tile(xt::xexpression<Expr> &data_expr, std::vector<size_t> ns){
        Expr &data = data_expr.derived_cast();
        data = xt::pad(data, ns, xt::pad_mode::reflect);
    }
     
    int main(){
       xt::xarray<int> a = xt::arange<int>(2);
       std::cout<<a<<"\n";
       std::vector<size_t> tile_vec = {2, 2};
       tile(a, tile_vec);
       std::cout<<a<<"\n";
    
       xt::xarray<int> b = xt::arange<int>(2);
       std::cout<<b<<"\n";
       b = xt::pad(b, {2,2}, xt::pad_mode::reflect);
       std::cout<<b<<"\n";
    }

    desired output:

    {0,1}
    {0,1,0,1,0,1}
    {0,1}
    {0,1,0,1,0,1}

    real output:

    {0,1}
    {1,0,1}
    {0,1}
    {1,0,1}

  3. tdegeus commented on Nov 28, 2019

    Member

    @tort-dla-psa At the level of xt::pad you've reached the limitation of the current implementation (that can clearly be improved!). For the moment xt::pad is not recursive, i.e. all pad modes that are not constant fail when the pad width is bigger than the shape along the relevant axis (or in the case of reflect the shape minus one).

    Upon enabling assertions:

    #define XTENSOR_ENABLE_ASSERT
    
    #include <xtensor/xarray.hpp>
    #include <xtensor/xpad.hpp>
    #include <xtensor/xio.hpp>
    
    int main()
    {
      xt::xarray<int> b = xt::arange<int>(2);
      std::cout << b << std::endl;
    
      b = xt::pad(b, {2, 2}, xt::pad_mode::reflect);
      std::cout << b << std::endl;
    
      return 0;
    }

    You will indeed find

    libc++abi.dylib: terminating with uncaught exception of type std::runtime_error: .../include/xtensor/xpad.hpp:138: assertion failed (nb <= out.shape()[axis] - 1)
    

    To clarify, currently:

    b = xt::pad(b, {2, 2}, xt::pad_mode::periodic); // works
    b = xt::pad(b, {3, 3}, xt::pad_mode::periodic); // throws
    b = xt::pad(b, {3, 3}, xt::pad_mode::constant); // works

    I think that the quickest fix for this would be to make xt::pad recursive. Obviously with the disadvantage of re-allocation more often than needed.

    We're very much open to improvements. In this regard I mention:

    With respect to you original issue of implementing xt::tile, I think that its stand-alone implementation could be faster than a generalisation of xt::pad (though the latter would obviously much more welcome).

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL