-
Notifications
You must be signed in to change notification settings - Fork 402
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
Conversation
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 But maybe that's something for the future? |
Thanks for tackling this. This is on the critical path in the short term for a lot of things. |
include/xtensor/xcontainer.hpp
Outdated
{ | ||
std::cout << "RESHAPING WITH COL_MAJOR" << std::endl; | ||
reshape(shape, layout::column_major); | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense
…s, make initialization from initializer list for column layout work
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:
while I just think it might be a lot of work ... Cheers, Wolf |
include/xtensor/xcontainer.hpp
Outdated
@@ -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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
include/xtensor/xcontainer.hpp
Outdated
else | ||
{ | ||
reshape(shape, layout::row_major); | ||
} | ||
} |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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 :)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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).
include/xtensor/xlayout.hpp
Outdated
}; | ||
} | ||
|
||
#endif |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
).
include/xtensor/xstrides.hpp
Outdated
@@ -14,15 +14,11 @@ | |||
#include <numeric> | |||
|
|||
#include "xexception.hpp" | |||
#include "xlayout.hpp" | |||
#include "xtensor_forward.hpp" | |||
|
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the catch
There was a problem hiding this comment.
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>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation should be updated
There was a problem hiding this comment.
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>> |
There was a problem hiding this comment.
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 | |||
*/ |
There was a problem hiding this comment.
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
include/xtensor/xstridedview.hpp
Outdated
CT m_e; | ||
const shape_type m_shape; | ||
const strides_type m_strides; | ||
const std::size_t m_offset; |
There was a problem hiding this comment.
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 | ||
|
There was a problem hiding this comment.
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
.
@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. |
@JohanMabille thanks! To remove all of the hacks in xblas it would be good if this lands as well :) |
@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. |
Remove the additional `xml` folder generated by `doxygen`
Fixup docs clean target
closing this in favor of the two new PR's. |
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
anddiag_view
.