Skip to content

set_data cannot deal with nodes without owners #5812

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

Closed
lucianopaz opened this issue May 27, 2022 · 5 comments · Fixed by #5817
Closed

set_data cannot deal with nodes without owners #5812

lucianopaz opened this issue May 27, 2022 · 5 comments · Fixed by #5817

Comments

@lucianopaz
Copy link
Member

lucianopaz commented May 27, 2022

Description of your problem

set_data seems to have a problem when the new coordinates are nodes without an owner.

Please provide a minimal, self-contained, and reproducible example.

import numpy as np
import pymc as pm


with pm.Model() as m:
    m.add_coord("a", np.arange(10), mutable=True)
    pm.MutableData("x", np.zeros(10), dims="a")

m.set_data("x", np.ones(5), coords={"a": np.arange(10, 15)})

Please provide the full traceback.

Complete error traceback
AttributeError                            Traceback (most recent call last)
<ipython-input-1-dc6231ed80dd> in <module>
      7     pm.MutableData("x", np.zeros(10), dims="a")
      8 
----> 9 m.set_data("x", np.ones(5), coords={"a": np.arange(10, 15)})

~/repos/pymc3/pymc/model.py in set_data(self, name, values, coords)
   1172                     )
   1173                 else:
-> 1174                     length_belongs_to = length_tensor.owner.inputs[0].owner.inputs[0]
   1175                     if not isinstance(length_belongs_to, SharedVariable):
   1176                         raise ShapeError(

AttributeError: 'NoneType' object has no attribute 'inputs'

Please provide any additional information below.

In the traceback, length_tensor is m.dim_lengths["a"]. The type of this variable is aesara.tensor.sharedvar.ScalarSharedVariable and it has no owners. I don't know when the owner logic was introduced, but it doesn't cover the simple case where the new coordinate is an array. Maybe this was intended? In any case, this should be fixed before releasing v4

Original code

Originally, I was running on an older version with respect to main. The code that I used was this

import numpy as np
import pymc as pm


coords = {"a": np.arange(10)}
with pm.Model(coords=coords) as m:
    pm.MutableData("x", np.zeros(10), dims="a")

m.set_data("x", np.ones(5), coords={"a": np.arange(10, 15)})
Which now leads to the following traceback instead
ShapeError                                Traceback (most recent call last)
<ipython-input-2-d7c5b13f43a6> in <module>
      7     pm.MutableData("x", np.zeros(10), dims="a")
      8 
----> 9 m.set_data("x", np.ones(5), coords={"a": np.arange(10, 15)})

~/repos/pymc3/pymc/model.py in set_data(self, name, values, coords)
   1164                         )
   1165                 if isinstance(length_tensor, TensorConstant):
-> 1166                     raise ShapeError(
   1167                         f"Resizing dimension '{dname}' is impossible, because "
   1168                         "a 'TensorConstant' stores its length. To be able "

ShapeError: Resizing dimension 'a' is impossible, because a 'TensorConstant' stores its length. To be able to change the dimension length, pass `mutable=True` when registering the dimension via `model.add_coord`, or define it via a `pm.MutableData` variable.

I think that it's rather strange not to be able to modify coordinates given via a constant tensor, but to be honest I didn't see when/where it was discussed.

Versions and main components

  • PyMC/PyMC3 Version: 4.0.0b6
  • Aesara/Theano Version:
  • Python Version:
  • Operating system:
  • How did you install PyMC/PyMC3: (conda/pip)
@lucianopaz lucianopaz added this to the v4.0.0 milestone May 27, 2022
@AlexAndorra
Copy link
Contributor

Interestingly, I don't get the same error message @lucianopaz !

ShapeError: Resizing dimension 'a' is impossible, because a 'TensorConstant' stores its length. To be able to change the dimension length, pass `mutable=True` when registering the dimension via `model.add_coord`, or define it via a `pm.MutableData` variable.

Interestingly, doing:

coords = {"a": np.arange(10)}

with pm.Model(coords=coords) as m:
    pm.MutableData("x", np.zeros(10), dims="a")

with m:
    pm.set_data(
        new_data={"x", np.ones(5)}, 
        coords={"a": np.arange(10, 15)}
    )

raises yet another error message 🤔

TypeError: unhashable type: 'numpy.ndarray'

@lucianopaz
Copy link
Member Author

@AlexAndorra is right. I wasn't using the latest version on master. I'll update the code to induce the original error again.

@michaelosthege
Copy link
Member

This was last changed in #5763 and I thought we had accounted for all scenarios in the tests.

@lucianopaz please check #5817 where I added your scenario as a test case.

@twiecki
Copy link
Member

twiecki commented Jun 3, 2022

Is this a critical blocker for 4.0?

@michaelosthege
Copy link
Member

The PR that fixes it is ready to merge IMO.
There were just nitpicks last time I checked

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants