-
Notifications
You must be signed in to change notification settings - Fork 46
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
Refactor: refactor the constructor of SimpleArray #439
Conversation
bfb8cea
to
c72e55f
Compare
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.
@yungyuc @tigercosmos Could you please review this pull request?
bool is_c_contiguous = true, | ||
bool is_f_contiguous = false) | ||
bool c_contiguous, | ||
bool f_contiguous) | ||
: SimpleArray(shape, stride, buffer) |
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.
In order to avoid
error: call to constructor of 'SimpleArray<bool>' is ambiguous
330 | return SimpleArray(shape, stride, buffer);
I don't assign the default value to c_contiguous
and f_contiguous
.
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.
Since we only have C type or F type, why not just:
explicit SimpleArray(small_vector<size_t> const & shape,
small_vector<size_t> const & stride,
std::shared_ptr<buffer_type> const & buffer,
bool is_c_contiguous = true)
I prefer using enum more, just for your reference:
enum class SimpleArrayMemoryType {
CType
FType
};
explicit SimpleArray(small_vector<size_t> const & shape,
small_vector<size_t> const & stride,
std::shared_ptr<buffer_type> const & buffer,
SimpleArrayMemoryType is_c_contiguous = SimpleArrayMemoryType::CType)
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.
Boolean flag does not need to introduce new symbols at the Python side and is preferred ATM.
The input buffer may be F or C contiguous or discontiguous. A single Boolean flag is not enough.
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.
And it's good to remove default arguments in C++. They usually do harm more than good.
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.
On the Python side, the argument can be a string; we already have the example from DataType
.
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.
It can, but using a string for a C++ enum is not the most robust implementation. It can be tolerated if the API is necessary. We do not need the enum so it's not the case here.
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.
By the way, if the array is 1 dimension, it could be c-contiguous and f-contiguous simultaneously, and I'm not sure enum is a good manner.
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.
By the way, if the array is 1 dimension, it could be c-contiguous and f-contiguous simultaneously, and I'm not sure enum is a good manner.
Good point. I overlooked the 1D case. But 1D should be a simple case. We can leave it here and revisit for a more complete solution in the future.
explicit SimpleArray(small_vector<size_t> const & shape, | ||
small_vector<size_t> const & stride, | ||
std::shared_ptr<buffer_type> const & buffer, | ||
bool is_c_contiguous = true, | ||
bool is_f_contiguous = false) | ||
bool c_contiguous, | ||
bool f_contiguous) | ||
: SimpleArray(shape, stride, buffer) | ||
{ | ||
if (shape.size() != stride.size()) | ||
{ | ||
throw std::runtime_error("SimpleArray: shape and stride size mismatch"); | ||
} | ||
if (c_contiguous) | ||
{ | ||
check_c_contiguous(shape, stride); | ||
} | ||
if (f_contiguous) | ||
{ | ||
check_f_contiguous(shape, stride); | ||
} | ||
} |
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.
@jteng2127 suggest that I could create a constructor with c_contiguous
and f_contiguous
, and this constructor could check the contiguous property and call another construcotr without c_contiguous
and f_contiguous
.
const bool is_c_contiguous = (arr_in.flags() & py::array::c_style) == py::array::c_style; | ||
const bool is_f_contiguous = (arr_in.flags() & py::array::f_style) == py::array::f_style; | ||
auto && is_c_contiguous = [&]() -> bool | ||
{ | ||
return (arr_in.flags() & py::array::c_style) == py::array::c_style; | ||
}; | ||
auto && is_f_contiguous = [&]() -> bool | ||
{ | ||
return (arr_in.flags() & py::array::f_style) == py::array::f_style; | ||
}; |
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'm not sure whether wrapping with lambda function is better than initializing the boolean variable.
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.
These lambda implementations work the same as direct evaluation. They do not simplify anything either. Please revert them.
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.
Good work! One thing to revert:
-
wrap_SimpleArray.cpp:87
: Revert the unnecessary lambdas.
bool is_c_contiguous = true, | ||
bool is_f_contiguous = false) | ||
bool c_contiguous, | ||
bool f_contiguous) | ||
: SimpleArray(shape, stride, buffer) |
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.
And it's good to remove default arguments in C++. They usually do harm more than good.
const bool is_c_contiguous = (arr_in.flags() & py::array::c_style) == py::array::c_style; | ||
const bool is_f_contiguous = (arr_in.flags() & py::array::f_style) == py::array::f_style; | ||
auto && is_c_contiguous = [&]() -> bool | ||
{ | ||
return (arr_in.flags() & py::array::c_style) == py::array::c_style; | ||
}; | ||
auto && is_f_contiguous = [&]() -> bool | ||
{ | ||
return (arr_in.flags() & py::array::f_style) == py::array::f_style; | ||
}; |
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.
These lambda implementations work the same as direct evaluation. They do not simplify anything either. Please revert them.
@@ -623,6 +608,37 @@ class SimpleArray | |||
value_type * body() { return m_body; } | |||
|
|||
private: | |||
void check_c_contiguous(small_vector<size_t> const & shape, |
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 like the helper functions.
They do not need to be in the class template because they do not use the template argument. But it's OK to keep them here for now.
There are other member functions that can be moved outside the class template. We only need to refactor when we run out of interesting things to do.
753353f
to
16857e5
Compare
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.
-
wrap_SimpleArray.cpp:87
: Revert the unnecessary lambdas.
Fixed. @yungyuc Could you please review this pull request?
16857e5
to
74a3a0f
Compare
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.
Perfect
bool is_c_contiguous = true, | ||
bool is_f_contiguous = false) | ||
bool c_contiguous, | ||
bool f_contiguous) | ||
: SimpleArray(shape, stride, buffer) |
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.
By the way, if the array is 1 dimension, it could be c-contiguous and f-contiguous simultaneously, and I'm not sure enum is a good manner.
Good point. I overlooked the 1D case. But 1D should be a simple case. We can leave it here and revisit for a more complete solution in the future.
In the pull request #438, @yungyuc mentioned that I could refactor the constructor.