aesara-devs / aehmc

An HMC/NUTS implementation in Aesara

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`test_hmc_mcse` unit test suddenly failing to pass due to `aesara.gradient.DisconnectedInputError` error.

zoj613 opened this issue · comments

commented

Description of your problem or feature request

CI tests are failing due to the tests for test_hmc_mcse raising a aesara.gradient.DisconnectedInputError exception.

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

python -m pytest tests/test_hmc.py::test_hmc_mcse -v

Please provide the full traceback of any errors.

tests/test_hmc.py:203:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../micromamba/envs/aehmc-dev/lib/python3.11/site-packages/aesara/scan/basic.py:864: in scan
    raw_inner_outputs = fn(*args)
aehmc/hmc.py:132: in step
    ), updates = proposal_generator(
aehmc/hmc.py:222: in propose
    ), updates = integrate(q, p, potential_energy, potential_energy_grad, step_size)
aehmc/trajectory.py:92: in integrate
    [q, p, energy, energy_grad], updates = aesara.scan(
../../micromamba/envs/aehmc-dev/lib/python3.11/site-packages/aesara/scan/basic.py:864: in scan
    raw_inner_outputs = fn(*args)
aehmc/trajectory.py:87: in one_step
    new_state = integrator(
aehmc/integrators.py:68: in one_step
    potential_energy_grad = aesara.grad(potential_energy, position)
../../micromamba/envs/aehmc-dev/lib/python3.11/site-packages/aesara/gradient.py:608: in grad
    handle_disconnected(elem)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

var = Elemwise{add,no_inplace}.0

    def handle_disconnected(var):
        message = (
            "grad method was asked to compute the gradient "
            "with respect to a variable that is not part of "
            "the computational graph of the cost, or is used "
            f"only by a non-differentiable operator: {var}"
        )
        if disconnected_inputs == "ignore":
            pass
        elif disconnected_inputs == "warn":
            warnings.warn(message, stacklevel=2)
        elif disconnected_inputs == "raise":
            message = utils.get_variable_trace_string(var)
>           raise DisconnectedInputError(message)
E           aesara.gradient.DisconnectedInputError:
E           Backtrace when that variable is created:
E
E             File "/home/zoj/dev/aehmc/tests/test_hmc.py", line 203, in test_hmc_mcse
E               trajectory, updates = aesara.scan(
E             File "/home/zoj/micromamba/envs/aehmc-dev/lib/python3.11/site-packages/aesara/scan/basic.py", line 864, in scan
E               raw_inner_outputs = fn(*args)
E             File "/home/zoj/dev/aehmc/aehmc/hmc.py", line 132, in step
E               ), updates = proposal_generator(
E             File "/home/zoj/dev/aehmc/aehmc/hmc.py", line 222, in propose
E               ), updates = integrate(q, p, potential_energy, potential_energy_grad, step_size)
E             File "/home/zoj/dev/aehmc/aehmc/trajectory.py", line 92, in integrate
E               [q, p, energy, energy_grad], updates = aesara.scan(
E             File "/home/zoj/micromamba/envs/aehmc-dev/lib/python3.11/site-packages/aesara/scan/basic.py", line 864, in scan
E               raw_inner_outputs = fn(*args)
E             File "/home/zoj/dev/aehmc/aehmc/trajectory.py", line 87, in one_step
E               new_state = integrator(
E             File "/home/zoj/dev/aehmc/aehmc/integrators.py", line 65, in one_step
E               position = position + a2 * step_size * kinetic_grad

../../micromamba/envs/aehmc-dev/lib/python3.11/site-packages/aesara/gradient.py:594: DisconnectedInputError

Versions and main components

  • Aesara version: 2.8.12
  • Aesara config (python -c "import aesara; print(aesara.config)")
  • Python version: 3.11
  • Operating system: Linux
  • How did you install Aesara: conda

This appears to be due to the position term in https://github.com/aesara-devs/aehmc/blob/main/aehmc/integrators.py#L68 no longer being present in the potential_energy term.

Here's a graph for those two terms:

>>> aesara.dprint([position, potential_energy])
Elemwise{add,no_inplace} [id A]
 |<TensorType(float64, (2,))> [id B]
 |Elemwise{add,no_inplace} [id C]
   |Elemwise{mul,no_inplace} [id D]
   | |TensorConstant{(1,) of 0.5} [id E]
   | |TensorConstant{(1,) of 1.0} [id F]
   | |Elemwise{sub,no_inplace} [id G]
   | | |<TensorType(float64, (2,))> [id H]
   | | |Elemwise{mul,no_inplace} [id I]
   | |   |TensorConstant{(1,) of 0.5} [id E]
   | |   |<TensorType(float64, (2,))> [id J]
   | |TensorConstant{[1. 2.]} [id K]
   |Elemwise{mul,no_inplace} [id L]
     |TensorConstant{(1,) of 0.5} [id E]
     |TensorConstant{(1,) of 1.0} [id F]
     |TensorConstant{[1. 2.]} [id K]
     |Elemwise{sub,no_inplace} [id G]
Elemwise{neg,no_inplace} [id M]
 |Sum{acc_dtype=float64} [id N]
   |Check{0 < diag(Sigma)} [id O]
     |Elemwise{sub,no_inplace} [id P]
     | |Elemwise{sub,no_inplace} [id Q]
     | | |Elemwise{mul,no_inplace} [id R]
     | | | |Elemwise{mul,no_inplace} [id S]
     | | | | |TensorConstant{-0.5} [id T]
     | | | | |Subtensor{int64} [id U]
     | | | |   |TensorConstant{(1,) of 2} [id V]
     | | | |   |ScalarConstant{-1} [id W]
     | | | |Elemwise{log,no_inplace} [id X]
     | | |   |TensorConstant{6.283185307179586} [id Y]
     | | |Elemwise{mul,no_inplace} [id Z]
     | |   |TensorConstant{0.5} [id BA]
     | |   |Sum{axis=[0], acc_dtype=float64} [id BB]
     | |     |Elemwise{pow,no_inplace} [id BC]
     | |       |InplaceDimShuffle{0} [id BD]
     | |       | |SolveTriangular{lower=True, trans=0, unit_diagonal=False, check_finite=True} [id BE]
     | |       |   |Elemwise{switch,no_inplace} [id BF]
     | |       |   | |InplaceDimShuffle{x,x} [id BG]
     | |       |   | | |All [id BH]
     | |       |   | |   |Elemwise{gt,no_inplace} [id BI]
     | |       |   | |     |ExtractDiag{offset=0, axis1=0, axis2=1, view=False} [id BJ]
     | |       |   | |     | |Cholesky{lower=True, destructive=False, on_error='nan'} [id BK]
     | |       |   | |     |   |TensorConstant{[[1. 1.]
 [1. 4.]]} [id BL]
     | |       |   | |     |InplaceDimShuffle{x} [id BM]
     | |       |   | |       |TensorConstant{0} [id BN]
     | |       |   | |Cholesky{lower=True, destructive=False, on_error='nan'} [id BK]
     | |       |   | |InplaceDimShuffle{x,x} [id BO]
     | |       |   |   |TensorConstant{1} [id BP]
     | |       |   |InplaceDimShuffle{0} [id BQ]
     | |       |     |Elemwise{sub,no_inplace} [id BR]
     | |       |       |Elemwise{add,no_inplace} [id BS]
     | |       |       | |<TensorType(float64, (2,))> [id B]
     | |       |       | |Elemwise{mul,no_inplace} [id BT]
     | |       |       | | |TensorConstant{(1,) of 0.5} [id E]
     | |       |       | | |Elemwise{sub,no_inplace} [id G]
     | |       |       | | |TensorConstant{[1. 2.]} [id K]
     | |       |       | |Elemwise{mul,no_inplace} [id BU]
     | |       |       |   |TensorConstant{(1,) of 0.5} [id E]
     | |       |       |   |TensorConstant{[1. 2.]} [id K]
     | |       |       |   |Elemwise{sub,no_inplace} [id G]
     | |       |       |TensorConstant{[0. 3.]} [id BV]
     | |       |InplaceDimShuffle{x} [id BW]
     | |         |TensorConstant{2} [id BX]
     | |Sum{acc_dtype=float64} [id BY]
     |   |Elemwise{log,no_inplace} [id BZ]
     |     |ExtractDiag{offset=0, axis1=0, axis2=1, view=False} [id BJ]
     |All [id BH]

The graph for position isn't present in potential_energy (e.g. id A isn't a node in the graph for potential_energy starting at id M), which explains the error. It looks like the subgraph starting at the node with id BS in the potential_energy graph is a copy/clone of position. We need that subgraph to be identical to position in order for position to be considered an "input" of potential_energy.

It looks like AePPL is doing some unnecessary cloning somewhere.

This was fixed in aesara-devs/aeppl#248 and will be available soon in release v0.1.4.