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

Add C++ StackNode #214

Closed
wants to merge 7 commits into from

Conversation

samuelbodin
Copy link
Contributor

Removed python implementation of stack which was using a combination of Reshape + Concatenate.
Python side now relies on C++ StackNode implementation.
Few updated tests, and new tests added for C++ and Python

@arcondello arcondello added the enhancement New feature or request label Jan 23, 2025
@arcondello arcondello requested a review from wbernoudy January 23, 2025 19:28
Comment on lines +687 to +688
if isinstance(arrays, ArraySymbol):
return arrays
Copy link
Member

Choose a reason for hiding this comment

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

What if axis is not 0? I know that numpy handles the case that arrays is itself an array, but it seems like maybe we should disallow it (as we are doing currently). Or perhaps there's a way to have it work with StackNode?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If the axis is not 0 then I guess that's a ValueError?

Copy link
Member

@arcondello arcondello Jan 24, 2025

Choose a reason for hiding this comment

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

Shouldn't support for non-0 axis be as simple as changing which index the 1 gets inserted to in the 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 don't believe so, as the ordering of the elements in the buffer needs to change as well, e.g.

>>> np.stack(np.arange(10).reshape(2, 5), axis=1).flatten()
array([0, 5, 1, 6, 2, 7, 3, 8, 4, 9])

Copy link
Member

Choose a reason for hiding this comment

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

The allocation is handled by the strides change. So the same shape/strides trick we used from concatenate should work here I believe.

Copy link
Member

Choose a reason for hiding this comment

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

#153 (comment) is what I mean

Copy link
Member

Choose a reason for hiding this comment

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

Oh sorry, I thought you meant it was a special case of reshape. You're right. The same trick works, but it does seem somewhat difficult to write code that handles both cases of the source arrays being separate operands or different slices of the same (single) operand. Especially since the latter will require examining the diff() of the single operand, but then determining which slice each update belongs to.

Certainly doable but it seems like you'll need to write a separate case in at least propagate() to handle it. Unless I'm missing something and you have another genius indexing trick in mind 😆

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm not sure I follow. What functionality are you suggesting we implement for input combination (ArraySymbol, non-zero axis)?

// Since stack adds a new dimension of size equal to the number
// of inputs, we need to do this for the strided iterator to work
std::vector<ssize_t> shape(this->shape().begin(), this->shape().end());
shape[this->axis_] = 1;
Copy link
Member

Choose a reason for hiding this comment

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

Smart! Perhaps worth saving this special shape on the class so you don't have to recreate it here and in initialize_state (with a comment explaining what it is). But current way is definitely fine as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah good point!

Copy link
Contributor Author

@samuelbodin samuelbodin Jan 24, 2025

Choose a reason for hiding this comment

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

9ef4955

with self.subTest("input arrays must have same shape and ndim"):
model = Model()
A = model.constant(np.arange(4).reshape((2,2)))
B = model.constant(np.arange(4).reshape((2,1,2)))
Copy link
Member

Choose a reason for hiding this comment

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

Should have spaces between elements in a tuple, I would do a quick check for that in the Python code and in Python examples in the docstrings

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah thanks, I went over that test too quickly and forgot about the formatting

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I see that the formatting is a bit off in several places. I'll do some work setting up a git hook so I don't forget the formatting all the time 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

b5bb60b

@arcondello
Copy link
Member

So I feel bad about this, but on reflection I think we should not add the C++ stack node. And do our stacking via Python with reshape and concatenate. We should add a Python hstack() and vstack() function though.

@arcondello arcondello closed this Jan 30, 2025
@arcondello
Copy link
Member

Made an issue for the Python implementations: #240

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants