-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Fix convert_size failure with 1d symbolic vectors #5417
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
Conversation
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.
Please add unit tests that can detect the original issue, ideally testing the function with all different kinds of inputs that should be supported according to its signature.
Also you should edit the description of the PR to explain what this is about: what was the problem with the original code and how do your changes fix it?
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 opening the PR. I've left a comment above
@ricardoV94 I made a new edit making sure it only accepts |
@5hv5hvnk We need tests showing that this is no longer an issue |
@ricardoV94 how do I make test cases and show that they are working? As of now when I tested few different things on the code that was in the initial issue itself and they work fine. |
Hi @5hv5hvnk, apologies for the delay. You can add a new test case in this function: pymc/pymc/tests/test_shape_handling.py Lines 463 to 468 in 9155922
Something like this might be enough: x = at.constant(5)
assert convert_size(x) is size
x = at.constant([5, 5])
assert convert_size(x) is size |
pymc/distributions/shape_utils.py
Outdated
if isinstance(size, int) or (isinstance(size, TensorVariable) and size.ndim==1 or size.ndim==0): | ||
size = tuple(size,) | ||
elif isinstance(size, (list, tuple)): | ||
size = tuple(size) | ||
else: |
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.
Does this work? I don't think we have to do anything if it is already a TensorVariable. We could assert it has ndim < 2
. but that's about it.
if isinstance(size, int) or (isinstance(size, TensorVariable) and size.ndim==1 or size.ndim==0): | |
size = tuple(size,) | |
elif isinstance(size, (list, tuple)): | |
size = tuple(size) | |
else: | |
if isinstance(size, int): | |
size = tuple(size,) | |
elif isinstance(size, (list, tuple)): | |
size = tuple(size) | |
elif not isinstance(TensorVariable): |
@5hv5hvnk This error also seems to be present in pymc/pymc/distributions/shape_utils.py Lines 475 to 476 in 90948a3
A similar fix should work there |
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.
Please run the pre-commit locally before pushing l:
pip install pre-commit
pre-commit run --all
pymc/distributions/shape_utils.py
Outdated
size = (size,) | ||
if isinstance(size, int): | ||
size = size | ||
elif isinstance(size,TensorVariable): |
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.
Please check for the ndim too (like a few lines above). For ndim>1 we still want to run into the exception case.
pymc/distributions/shape_utils.py
Outdated
elif isinstance(size, TensorVariable) and size.ndim <= 1: | ||
size = tuple(size) |
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.
tuple(size)
does't work when size.ndim == 0
.
The 0 and 1 ndim must be separate cases
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.
does to_tuple
work?
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.
something like this would be sufficient ?
if isinstance(shape, int) or (isinstance(size,TensorVariable) and shape.ndim==0):
shape = shape
if isinstance(shape, TensorVariable) and shape.ndim == 1:
shape = tuple(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.
Just keep the code that was there before and add another elif case:
if isinstance(size, int) or (isinstance(size, TensorVariable) and size.ndim == 0):
size = (size,)
elif isinstance(size, TensorVariable) and size.ndim == 1:
size = tuple(size)
And the same further up in convert_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.
on using
pre-commit run --all
all the tests are passed, however it shows build failed when I commit the changes how can I resolve this?
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.
Precommit is not running tests, but other things like linters and code format checks. The output should tell you what the fix is, or automatically add the changes to git staging. Feel free to post a screenshot of the output and we can more specifically let you know what to do!
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.
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.
Im not sure what you mean by build. This indicates the commit should have taken place. What happens when you try and push it to github?
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 your branch could be outdated. The pre-commit in the CI failed in the type checking step but that step did not run in your screenshot.
Do the following to update your branch:
- Make sure that you don't have uncommitted changes (commit, stash or revert them if needed)
git checkout main
git pull
git checkout my-feature
to go back to the branch of this PRgit rebase main
to rebase the PR branch onto main. Since GitHub doesn't show any merge conflicts this step should work without problems.
Then run pre-commit
again. This time it should reproduce the failure from the CI.
pymc/distributions/shape_utils.py
Outdated
@@ -449,9 +449,10 @@ def convert_shape(shape: Shape) -> Optional[WeakShape]: | |||
"""Process a user-provided shape variable into None or a valid shape object.""" | |||
if shape is None: | |||
return None | |||
|
|||
if isinstance(shape, int) or (isinstance(shape, TensorVariable) and shape.ndim == 0): | |||
if isinstance(shape, int) or (isinstance(size, TensorVariable) and shape.ndim == 0): |
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 would add parentheses around the or statement conditionsm its not strictly needed but it makes the code intent much more obvious
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 don't mind the parantheses, but in the 2nd isinstance you changed shape to size.
This line should have no change at all
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 canceled the CI workflows because the pre-commit was failing.
Please run pre-commit before pushing to reduce the CI workload.
pymc/distributions/shape_utils.py
Outdated
@@ -449,9 +449,10 @@ def convert_shape(shape: Shape) -> Optional[WeakShape]: | |||
"""Process a user-provided shape variable into None or a valid shape object.""" | |||
if shape is None: | |||
return None | |||
|
|||
if isinstance(shape, int) or (isinstance(shape, TensorVariable) and shape.ndim == 0): | |||
if isinstance(shape, int) or (isinstance(size, TensorVariable) and shape.ndim == 0): |
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 don't mind the parantheses, but in the 2nd isinstance you changed shape to size.
This line should have no change at all
pymc/distributions/shape_utils.py
Outdated
shape = (shape,) | ||
if isinstance(shape, TensorVariable) and shape.ndim == 1: |
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.
This should be an elif
Noted, and thank you |
The diff looks good. |
Codecov Report
@@ Coverage Diff @@
## main #5417 +/- ##
===========================================
- Coverage 81.39% 63.08% -18.31%
===========================================
Files 82 76 -6
Lines 14213 13779 -434
===========================================
- Hits 11568 8693 -2875
- Misses 2645 5086 +2441
|
|
@5hv5hvnk You need to pull main and then rebase your branch and force-push: https://stackoverflow.com/questions/8965781/update-an-outdated-branch-against-master-in-a-git-repo |
This shows my branch is up to the date I still used push --force to push it to the main branch |
@5hv5hvnk This is your fork, you can add the pymc-devs repo as a remote and then pull to main from there and then rebase. |
convert_size
wrongly assumes symbolic sizes have to be scalarsfixed by changing code in
pymc/pymc/distributions/shape_utils.py
Line 475 in 9155922
by accepting
size.ndim == 1
as well assize.ndim == 0
Closes #5394