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

Refactor: refactor the constructor of SimpleArray #439

Merged
merged 1 commit into from
Dec 7, 2024

Conversation

ThreeMonth03
Copy link
Collaborator

In the pull request #438, @yungyuc mentioned that I could refactor the constructor.

Copy link
Collaborator Author

@ThreeMonth03 ThreeMonth03 left a 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?

Comment on lines -315 to +317
bool is_c_contiguous = true,
bool is_f_contiguous = false)
bool c_contiguous,
bool f_contiguous)
: SimpleArray(shape, stride, buffer)
Copy link
Collaborator Author

@ThreeMonth03 ThreeMonth03 Dec 4, 2024

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.

Copy link
Collaborator

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)

Copy link
Member

@yungyuc yungyuc Dec 5, 2024

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.

Copy link
Member

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.

Copy link
Collaborator

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.

Copy link
Member

@yungyuc yungyuc Dec 5, 2024

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.

Copy link
Collaborator Author

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.

Copy link
Member

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.

Comment on lines 312 to +331
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);
}
}
Copy link
Collaborator Author

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.

Comment on lines 87 to 94
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;
};
Copy link
Collaborator Author

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.

Copy link
Member

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.

Copy link
Member

@yungyuc yungyuc left a 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:

Comment on lines -315 to +317
bool is_c_contiguous = true,
bool is_f_contiguous = false)
bool c_contiguous,
bool f_contiguous)
: SimpleArray(shape, stride, buffer)
Copy link
Member

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.

Comment on lines 87 to 94
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;
};
Copy link
Member

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,
Copy link
Member

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.

@yungyuc yungyuc added refactor Change code without changing tests array Multi-dimensional array implementation labels Dec 5, 2024
@ThreeMonth03 ThreeMonth03 force-pushed the issue432 branch 2 times, most recently from 753353f to 16857e5 Compare December 6, 2024 19:03
Copy link
Collaborator Author

@ThreeMonth03 ThreeMonth03 left a comment

Choose a reason for hiding this comment

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

Fixed. @yungyuc Could you please review this pull request?

Copy link
Member

@yungyuc yungyuc left a comment

Choose a reason for hiding this comment

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

Perfect

Comment on lines -315 to +317
bool is_c_contiguous = true,
bool is_f_contiguous = false)
bool c_contiguous,
bool f_contiguous)
: SimpleArray(shape, stride, buffer)
Copy link
Member

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.

@yungyuc yungyuc merged commit 2e43e1f into solvcon:master Dec 7, 2024
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
array Multi-dimensional array implementation refactor Change code without changing tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants