Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Initial xstrided_view and adding layout template parameter #240

Closed
wants to merge 16 commits into from

Conversation

wolfv
Copy link
Member

@wolfv wolfv commented Apr 4, 2017

This adds layout as template parameter for xarray so far, and an initial implementation for xstrided_view.

On top of xstrided_view there are basic implementations of transpose_view and diag_view.

@wolfv
Copy link
Member Author

wolfv commented Apr 4, 2017

The biggest drawback is that those methods won't work on non-strided containers (e.g. xgenerators).

We could add methods to make it work by computing strides if necessary. Through xstridedview we could also provide a generic reshape method.

But maybe that's something for the future?

@SylvainCorlay
Copy link
Member

Thanks for tackling this. This is on the critical path in the short term for a lot of things.

{
std::cout << "RESHAPING WITH COL_MAJOR" << std::endl;
reshape(shape, layout::column_major);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that we should default to row_major, instead of defaulting to column_major when the layout type is custom.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

wolfv added 2 commits April 5, 2017 16:00
…s, make initialization from initializer list for column layout work
@wolfv
Copy link
Member Author

wolfv commented Apr 6, 2017

Ok, I've reworked this once more to use the layout enum as template parameter.

At this point I'd be happy for a review.

It still needs more tests I guess. For example, checking that xexpressions with column_major and row_major containers work as expected. If r is row_major and c is column_major, this fails:

c = {{1,2,3}, {4,5,6}};
r = {{1,2,3}, {4,5,6}};
all(equal(c, r));

while equal(c, r) actually prints the correct result. That is probably, because all uses cbegin and cend (it works with xbegin/end.
So I guess we could work around this by checking both expressions, and use the fast iterators only if both are equal, and otherwise fall back to a slow method.

I just think it might be a lot of work ...

Cheers,

Wolf

@@ -220,7 +190,7 @@ namespace xt
using inner_strides_type = typename base_type::inner_strides_type;
using inner_backstrides_type = typename base_type::inner_backstrides_type;

void reshape(const shape_type& shape);
void reshape(const shape_type& shape, bool force = false);
void reshape(const shape_type& shape, layout l);
void reshape(const shape_type& shape, const strides_type& strides);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The last two overloads should be available for dynamic layout only. Else you may end up with a container whose strides are not consistent with the layout.

Copy link
Member Author

@wolfv wolfv Apr 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could also add static_asserts in the function to only allow reshaping with a different layout if L == dynamic? That would keep the interface consistent.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find it strange to provide methods that may fail to compile, depending the template parameters you use. Most of the times, people need the reshape overload that takes the new shape only, other overloads are provided for tuning / optimization. Enabling these last ones for dynamic layout only doesn't make the interface more inconsistent thant providing reshape methods for containers only, for instance.

Maybe the cleanest way would be to provide these methods in a specialization of the strided_container class, but that would be a bit of overkill imo.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think one benefit of static_asserts would be that we could print a helpful error message, e.g. "reshaping with layout parameter only possible if layout == dynamic".
I have changed it now, though, to disable reshaping with layout if L != dynamic.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I tried this, but it requires rewriting almost all constructors for xarray and xtensor.

Copy link
Member

@JohanMabille JohanMabille Apr 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that it means enabling/disabling them depending on the layout template parameter ? Let's fallback to static_asserts for now if it's less time consuming, we will potentially refactor them later.

else
{
reshape(shape, layout::row_major);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The layout is know at compile time, so it might be better to rely on that and select the appropriated reshape with some metaprogramming tools (tag dispatching or specializations of private implementation structures)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was hoping that the compiler would be smart enough to just remove the false statement anyways, but sure, we can do some metaprogramming :)

Copy link
Member

@JohanMabille JohanMabille Apr 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed the compiler will remove the false statement, but it will check the syntax of every statement. This remark was to be consistent with assuming that the reshape overloads are enabled for dynamic layout only.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a member variable m_layout which and changed the logic slightly (will be in the next commit).

};
}

#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for moving this out of xstrides.hpp ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it isn't possible to forward declare an enum, but I needed the declaration in forward_xtensor. We could also put the enum in forward_xtensor.hpp. What do you think?

Copy link
Member

@JohanMabille JohanMabille Apr 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually starting with C++11 you can forward declare an enum as long as you provide the storage type. But since you need to provide a default layout for xtensor and xarray aliases, you need to know the enum definition in xtensor_forward.hpp. So it might be relevant to define it here (I prefer not to include any other header in xtensor_forward.hpp).

@@ -14,15 +14,11 @@
#include <numeric>

#include "xexception.hpp"
#include "xlayout.hpp"
#include "xtensor_forward.hpp"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

xtensor_forward.hpp should not be included here since we do not manipulate tensor types in this file. If this is required by other files including xstrides.hpp, then add the include in these files rather than in this one.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the catch

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you define the layout enum in xtensor_forward.hpp I think you will entually keep the include here.

@@ -43,10 +46,10 @@ namespace xt
* @tparam A The allocator of the container holding the elements.
* @tparam SA The allocator of the containers holding the shape and the strides.
*/
template <class T, class A = std::allocator<T>, class SA = std::allocator<typename std::vector<T, A>::size_type>>
using xarray = xarray_container<DEFAULT_DATA_CONTAINER(T, A), DEFAULT_SHAPE_CONTAINER(T, A, SA)>;
template <class T, layout L = layout::row_major, class A = std::allocator<T>, class SA = std::allocator<typename std::vector<T, A>::size_type>>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation should be updated

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep!

@@ -68,8 +71,8 @@ namespace xt
* @tparam N The dimension of the tensor.
* @tparam A The allocator of the containers holding the elements.
*/
template <class T, std::size_t N, class A = std::allocator<T>>
using xtensor = xtensor_container<DEFAULT_DATA_CONTAINER(T, A), N>;
template <class T, std::size_t N, layout L = layout::row_major, class A = std::allocator<T>>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too :) The same for other types in this file

@@ -53,15 +53,15 @@ namespace xt
* @tparam SC The type of the containers holding the shape and the strides.
* @sa xarray
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation should be updated, the same for types in xtensor.hpp

CT m_e;
const shape_type m_shape;
const strides_type m_strides;
const std::size_t m_offset;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why making these members const ? This prevents you from reshaping and transposing in place. Not sure we want to allow that, though.

template <class I, std::size_t N, class Tag = check_policy::none>
void transpose(const I (&permutation)[N], Tag check_policy = Tag());
#endif

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should keep the transpose methods for containers with dynamic layout. That would allow "in-place" transposition, but may be confusing with the methods provided in xstridedview.hpp.

@JohanMabille
Copy link
Member

@wolfv Thanks for implementing this, I made a quick review as you can see, I'll go into more details after pydata. Indeed there is still a lot of work to make the static layout working everywhere (assignment, iterators, functions), but I think it may be done in another PR; actually I have a good idea of how to do that and I need it to implement SIMD.

@wolfv
Copy link
Member Author

wolfv commented Apr 6, 2017

@JohanMabille thanks! To remove all of the hacks in xblas it would be good if this lands as well :)
We should definitly coordinate how we want to go about this. If you think this has enough features to land in master with some minor fixes than I'd stop working on it and we fix the bunch of tests where col and row layout are mixed in a later PR?

@JohanMabille
Copy link
Member

JohanMabille commented Apr 6, 2017

@wolfv if this PR is enough so that you can clean up xblas, we can merge it in master as soon as you have pushed the minor fixes we mentioned earlier. I will start to work on propagating the layout to assignment, iterators and functions just after our talk this sunday. We will update the documentation with more details about layout once everything is working.

Besides, that will fix #161 and #231.

@wolfv
Copy link
Member Author

wolfv commented Apr 7, 2017

closing this in favor of the two new PR's.

@wolfv wolfv closed this Apr 7, 2017
@wolfv wolfv deleted the xstrided_view branch October 30, 2017 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants