Skip to content

Handle new PyTensor v3 breaking changes#8243

Open
jessegrabowski wants to merge 13 commits intov6from
clean-pytensor-imports
Open

Handle new PyTensor v3 breaking changes#8243
jessegrabowski wants to merge 13 commits intov6from
clean-pytensor-imports

Conversation

@jessegrabowski
Copy link
Copy Markdown
Member

@jessegrabowski jessegrabowski commented Apr 8, 2026

No description provided.

@read-the-docs-community
Copy link
Copy Markdown

read-the-docs-community bot commented Apr 8, 2026

Documentation build overview

📚 pymc | 🛠️ Build #32202720 | 📁 Comparing d9c48b8 against latest (4b0b6ee)

  🔍 Preview build  

Show files changed (214 files in total): 📝 210 modified | ➕ 4 added | ➖ 0 deleted
File Status
genindex.html 📝 modified
glossary.html 📝 modified
api/backends.html 📝 modified
api/logprob.html 📝 modified
contributing/developer_guide.html 📝 modified
_modules/pymc/data.html 📝 modified
_modules/pymc/pytensorf.html 📝 modified
_modules/pymc/testing.html 📝 modified
api/distributions/multivariate.html 📝 modified
api/generated/pymc.backends.zarr.ZarrTrace.html 📝 modified
api/generated/pymc.compute_deterministics.html 📝 modified
api/generated/pymc.compute_log_likelihood.html 📝 modified
api/generated/pymc.compute_log_prior.html 📝 modified
api/generated/pymc.draw.html 📝 modified
api/generated/pymc.icdf.html 📝 modified
api/generated/pymc.logcdf.html 📝 modified
api/generated/pymc.logp.html 📝 modified
api/generated/pymc.ode.DifferentialEquation.html 📝 modified
api/generated/pymc.predictions_to_inference_data.html 📝 modified
api/generated/pymc.sample_posterior_predictive.html 📝 modified
api/generated/pymc.sample_prior_predictive.html 📝 modified
api/generated/pymc.sampling.jax.sample_blackjax_nuts.html 📝 modified
api/generated/pymc.sampling.jax.sample_numpyro_nuts.html 📝 modified
api/generated/pymc.smc.sample_smc.html 📝 modified
api/generated/pymc.to_inference_data.html 📝 modified
learn/core_notebooks/dimensionality.html 📝 modified
learn/core_notebooks/dims_module.html 📝 modified
learn/core_notebooks/model_comparison.html 📝 modified
learn/core_notebooks/posterior_predictive.html 📝 modified
learn/core_notebooks/pymc_overview.html 📝 modified
_modules/pymc/backends/arviz.html 📝 modified
_modules/pymc/backends/base.html 📝 modified
_modules/pymc/backends/ndarray.html 📝 modified
_modules/pymc/backends/zarr.html 📝 modified
_modules/pymc/distributions/continuous.html 📝 modified
_modules/pymc/distributions/custom.html 📝 modified
_modules/pymc/distributions/discrete.html 📝 modified
_modules/pymc/distributions/distribution.html 📝 modified
_modules/pymc/distributions/mixture.html 📝 modified
_modules/pymc/distributions/multivariate.html 📝 modified
_modules/pymc/distributions/shape_utils.html 📝 modified
_modules/pymc/distributions/timeseries.html 📝 modified
_modules/pymc/distributions/transforms.html 📝 modified
_modules/pymc/distributions/truncated.html 📝 modified
_modules/pymc/logprob/basic.html 📝 modified
_modules/pymc/model/core.html 📝 modified
_modules/pymc/model/fgraph.html 📝 modified
_modules/pymc/ode/ode.html 📝 modified
_modules/pymc/sampling/deterministic.html 📝 modified
_modules/pymc/sampling/forward.html 📝 modified
_modules/pymc/sampling/mcmc.html 📝 modified
_modules/pymc/smc/sampling.html 📝 modified
_modules/pymc/stats/log_density.html 📝 modified
_modules/pymc/tuning/starting.html 📝 modified
_modules/pymc/variational/approximations.html 📝 modified
_modules/pymc/variational/operators.html 📝 modified
_modules/pymc/variational/opvi.html 📝 modified
_modules/pytensor/tensor/basic.html 📝 modified
_modules/pytensor/tensor/extra_ops.html 📝 modified
_modules/pytensor/tensor/math.html 📝 modified
_modules/pytensor/tensor/special.html 📝 modified
api/dims/generated/pymc.dims.Beta.html 📝 modified
api/dims/generated/pymc.dims.Cauchy.html 📝 modified
api/dims/generated/pymc.dims.Gamma.html 📝 modified
api/dims/generated/pymc.dims.HalfCauchy.html 📝 modified
api/dims/generated/pymc.dims.HalfNormal.html 📝 modified
api/dims/generated/pymc.dims.HalfStudentT.html 📝 modified
api/dims/generated/pymc.dims.InverseGamma.html 📝 modified
api/dims/generated/pymc.dims.Laplace.html 📝 modified
api/dims/generated/pymc.dims.LogNormal.html 📝 modified
api/dims/generated/pymc.dims.Normal.html 📝 modified
api/dims/generated/pymc.dims.StudentT.html 📝 modified
api/dims/generated/pymc.dims.TruncatedNormal.html 📝 modified
api/dims/generated/pymc.dims.Uniform.html 📝 modified
api/dims/generated/pymc.dims.Weibull.html 📝 modified
api/distributions/classmethods/pymc.Censored.dist.html 📝 modified
api/distributions/classmethods/pymc.Simulator.dist.html 📝 modified
api/distributions/classmethods/pymc.Truncated.dist.html 📝 modified
api/distributions/generated/pymc.Bernoulli.html 📝 modified
api/distributions/generated/pymc.Beta.html 📝 modified
api/distributions/generated/pymc.BetaBinomial.html 📝 modified
api/distributions/generated/pymc.Binomial.html 📝 modified
api/distributions/generated/pymc.Categorical.html 📝 modified
api/distributions/generated/pymc.Cauchy.html 📝 modified
api/distributions/generated/pymc.ChiSquared.html 📝 modified
api/distributions/generated/pymc.Continuous.html 📝 modified
api/distributions/generated/pymc.Discrete.html 📝 modified
api/distributions/generated/pymc.DiscreteUniform.html 📝 modified
api/distributions/generated/pymc.DiscreteWeibull.html 📝 modified
api/distributions/generated/pymc.Distribution.html 📝 modified
api/distributions/generated/pymc.ExGaussian.html 📝 modified
api/distributions/generated/pymc.Exponential.html 📝 modified
api/distributions/generated/pymc.Gamma.html 📝 modified
api/distributions/generated/pymc.Geometric.html 📝 modified
api/distributions/generated/pymc.Gumbel.html 📝 modified
api/distributions/generated/pymc.HalfCauchy.html 📝 modified
api/distributions/generated/pymc.HalfNormal.html 📝 modified
api/distributions/generated/pymc.HalfStudentT.html 📝 modified
api/distributions/generated/pymc.HyperGeometric.html 📝 modified
api/distributions/generated/pymc.Interpolated.html 📝 modified
api/distributions/generated/pymc.InverseGamma.html 📝 modified
api/distributions/generated/pymc.Kumaraswamy.html 📝 modified
api/distributions/generated/pymc.LKJCorr.html 📝 modified
api/distributions/generated/pymc.Laplace.html 📝 modified
api/distributions/generated/pymc.LogNormal.html 📝 modified
api/distributions/generated/pymc.Logistic.html 📝 modified
api/distributions/generated/pymc.LogitNormal.html 📝 modified
api/distributions/generated/pymc.Moyal.html 📝 modified
api/distributions/generated/pymc.NegativeBinomial.html 📝 modified
api/distributions/generated/pymc.Normal.html 📝 modified
api/distributions/generated/pymc.Pareto.html 📝 modified
api/distributions/generated/pymc.Poisson.html 📝 modified
api/distributions/generated/pymc.PolyaGamma.html 📝 modified
api/distributions/generated/pymc.Rice.html 📝 modified
api/distributions/generated/pymc.SkewNormal.html 📝 modified
api/distributions/generated/pymc.StudentT.html 📝 modified
api/distributions/generated/pymc.SymbolicRandomVariable.html 📝 modified
api/distributions/generated/pymc.Triangular.html 📝 modified
api/distributions/generated/pymc.TruncatedNormal.html 📝 modified
api/distributions/generated/pymc.Uniform.html 📝 modified
api/distributions/generated/pymc.VonMises.html 📝 modified
api/distributions/generated/pymc.Wald.html 📝 modified
api/distributions/generated/pymc.Weibull.html 📝 modified
api/distributions/generated/pymc.ZeroInflatedBinomial.html 📝 modified
api/distributions/generated/pymc.ZeroInflatedNegativeBinomial.html 📝 modified
api/distributions/generated/pymc.ZeroInflatedPoisson.html 📝 modified
api/generated/classmethods/pymc.backends.NDArray.point.html 📝 modified
api/generated/classmethods/pymc.backends.base.BaseTrace.point.html 📝 modified
api/generated/classmethods/pymc.backends.zarr.ZarrChain.point.html 📝 modified
api/generated/classmethods/pymc.backends.zarr.ZarrTrace.to_inferencedata.html 📝 modified
api/generated/classmethods/pymc.ode.DifferentialEquation.L_op.html 📝 modified
api/generated/classmethods/pymc.ode.DifferentialEquation.R_op.html 📝 modified
api/generated/classmethods/pymc.ode.DifferentialEquation.do_constant_folding.html 📝 modified
api/generated/classmethods/pymc.ode.DifferentialEquation.grad.html 📝 modified
api/generated/classmethods/pymc.ode.DifferentialEquation.prepare_node.html 📝 modified
api/generated/classmethods/pymc.ode.DifferentialEquation.pullback.html ➕ added
api/generated/classmethods/pymc.ode.DifferentialEquation.pushforward.html ➕ added
_modules/pymc/dims/distributions/censored.html 📝 modified
_modules/pymc/dims/distributions/scalar.html 📝 modified
_modules/pymc/dims/distributions/vector.html 📝 modified
_modules/pymc/model/transform/optimization.html 📝 modified
api/distributions/generated/classmethods/pymc.AR.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.AsymmetricLaplace.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Bernoulli.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Beta.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.BetaBinomial.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Binomial.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.CAR.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Categorical.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Cauchy.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Continuous.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.DiracDelta.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Dirichlet.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.DirichletMultinomial.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Discrete.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.DiscreteUniform.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.DiscreteWeibull.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Distribution.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.EulerMaruyama.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.ExGaussian.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Exponential.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Flat.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.GARCH11.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Gamma.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Geometric.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Gumbel.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.HalfCauchy.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.HalfFlat.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.HalfNormal.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.HalfStudentT.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.HyperGeometric.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.ICAR.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Interpolated.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.InverseGamma.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.KroneckerNormal.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Kumaraswamy.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.LKJCorr.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Laplace.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.LogNormal.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Logistic.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.MatrixNormal.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Mixture.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Moyal.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Multinomial.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.MvNormal.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.MvStudentT.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.NegativeBinomial.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Normal.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Pareto.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Poisson.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.PolyaGamma.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Rice.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.SkewNormal.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.SkewStudentT.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.StickBreakingWeights.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.StudentT.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.SymbolicRandomVariable.L_op.html 📝 modified
api/distributions/generated/classmethods/pymc.SymbolicRandomVariable.R_op.html 📝 modified
api/distributions/generated/classmethods/pymc.SymbolicRandomVariable.do_constant_folding.html 📝 modified
api/distributions/generated/classmethods/pymc.SymbolicRandomVariable.grad.html 📝 modified
api/distributions/generated/classmethods/pymc.SymbolicRandomVariable.prepare_node.html 📝 modified
api/distributions/generated/classmethods/pymc.SymbolicRandomVariable.pullback.html ➕ added
api/distributions/generated/classmethods/pymc.SymbolicRandomVariable.pushforward.html ➕ added
api/distributions/generated/classmethods/pymc.SymbolicRandomVariable.rebuild_rv.html 📝 modified
api/distributions/generated/classmethods/pymc.SymbolicRandomVariable.update.html 📝 modified
api/distributions/generated/classmethods/pymc.Triangular.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.TruncatedNormal.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Uniform.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.VonMises.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Wald.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Weibull.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.Wishart.dist.html 📝 modified
api/distributions/generated/classmethods/pymc.ZeroSumNormal.dist.html 📝 modified
api/model/generated/classmethods/pymc.model.core.Model.compile_fn.html 📝 modified

@ricardoV94 ricardoV94 force-pushed the clean-pytensor-imports branch from 1a4bf41 to 2c59b8c Compare April 9, 2026 07:57
@ricardoV94 ricardoV94 force-pushed the clean-pytensor-imports branch from 2c59b8c to e7f4940 Compare April 9, 2026 08:10
@ricardoV94 ricardoV94 changed the title Clean pytensor imports Update to new PyTensor v3 breaking changes Apr 9, 2026
@ricardoV94 ricardoV94 added this to the v6 milestone Apr 9, 2026
@ricardoV94 ricardoV94 force-pushed the clean-pytensor-imports branch from 317229d to 9a064f0 Compare April 9, 2026 10:27
@ricardoV94 ricardoV94 changed the title Update to new PyTensor v3 breaking changes Handle new PyTensor v3 breaking changes Apr 9, 2026
@ricardoV94 ricardoV94 force-pushed the clean-pytensor-imports branch from 9a064f0 to 7db53a1 Compare April 9, 2026 10:33
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 9, 2026

Codecov Report

❌ Patch coverage is 99.20000% with 1 line in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (v6@627eb74). Learn more about missing BASE report.

Files with missing lines Patch % Lines
pymc/dims/distributions/censored.py 83.33% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@          Coverage Diff          @@
##             v6    #8243   +/-   ##
=====================================
  Coverage      ?   88.35%           
=====================================
  Files         ?      124           
  Lines         ?    19962           
  Branches      ?        0           
=====================================
  Hits          ?    17638           
  Misses        ?     2324           
  Partials      ?        0           
Files with missing lines Coverage Δ
pymc/backends/arviz.py 95.30% <100.00%> (ø)
pymc/backends/base.py 88.26% <100.00%> (ø)
pymc/backends/ndarray.py 79.81% <100.00%> (ø)
pymc/data.py 85.07% <100.00%> (ø)
pymc/dims/distributions/core.py 91.70% <100.00%> (ø)
pymc/dims/distributions/scalar.py 96.61% <100.00%> (ø)
pymc/dims/distributions/vector.py 90.00% <100.00%> (ø)
pymc/distributions/continuous.py 98.18% <100.00%> (ø)
pymc/distributions/custom.py 95.56% <100.00%> (ø)
pymc/distributions/discrete.py 99.42% <100.00%> (ø)
... and 23 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ricardoV94 ricardoV94 force-pushed the clean-pytensor-imports branch 2 times, most recently from 3bfe4fb to ff4a930 Compare April 9, 2026 11:53
@ricardoV94
Copy link
Copy Markdown
Member

Truncation test failing. Bot came up with this MWE, I didn't have time to check, suspect the issue is in PyMC not PyTensor.

"""Pytensor scan + until + OpFromGraph (with rng inputs) drops rng updates.

Without ``until`` the same scan body propagates the rng updates correctly
across iterations.  With ``until`` the inner OpFromGraph's rng inputs are
stuck on their initial values and every iteration produces identical draws.
"""
import warnings
warnings.simplefilter("ignore")

import numpy as np
import pytensor
import pytensor.tensor as pt
from pytensor.scan import scan, until

from pymc import HalfNormal, LogNormal, Mixture, CustomDist
from pymc.pytensorf import collect_default_updates


def mix_dist_fn(size):
    return Mixture.dist(
        w=[0.3, 0.7],
        comp_dists=[HalfNormal.dist(), LogNormal.dist()],
        shape=size,
    )


x = CustomDist.dist(dist=mix_dist_fn, shape=(5,))


def loop_fn_no_until(prev, *rngs):
    new = x.owner.op.make_node(*rngs).default_output()
    return new, collect_default_updates(new)


def loop_fn_until(prev, *rngs):
    new = x.owner.op.make_node(*rngs).default_output()
    return new, collect_default_updates(new), until(pt.all(new < -100))


print("=== no until ===")
out, updates = scan(
    loop_fn_no_until,
    outputs_info=[pt.zeros((5,))],
    non_sequences=list(x.owner.inputs),
    n_steps=3,
    strict=True,
)
print(pytensor.function([], out, updates=updates)())

print("=== with until ===")
out, updates = scan(
    loop_fn_until,
    outputs_info=[pt.zeros((5,))],
    non_sequences=list(x.owner.inputs),
    n_steps=3,
    strict=True,
)
print(pytensor.function([], out, updates=updates)())

@ricardoV94
Copy link
Copy Markdown
Member

This is blocked on pymc-devs/pytensor#2039

@ricardoV94 ricardoV94 force-pushed the clean-pytensor-imports branch 2 times, most recently from b89e6f6 to c3a9400 Compare April 10, 2026 12:44
The xfail was added during the aeppl integration (0a172c8) because
the analytical log_jac_det and the numerical det(jacobian) baseline
diverged by ~3e-5. Investigation shows the analytical log_jac_det is
correct and the numerical baseline is the imprecise side.

For the worst-case input y=[2.1, 2.1, 2.1, 2.1], mpmath (50 digits)
confirms:

  true log|det(J)|:         -51.328128121070321
  analytical log_jac_det:   -51.328128121070336  (error: 1.4e-14)
  numerical det(jacobian):  -51.328096462874562  (error: 3.2e-05)

Root cause: PyTensor's autodiff computes expit'(z) as
expit(z) * (1 - expit(z)). For large z (e.g., 26.6), expit(z) rounds
to ~1.0 and the subtraction 1 - expit(z) loses precision. A more
stable form would be expit(z) * expit(-z).

Reproducible with mpmath:

  from mpmath import mp, mpf, log, exp, matrix, det
  mp.dps = 50
  y = [mpf('2.1')] * 4
  def expit(z): return 1 / (1 + exp(-z))
  v = [y[0]]
  for i in range(1, 4): v.append(v[-1] + exp(y[i]))
  J = matrix(4, 4)
  for i in range(4):
      sp = expit(v[i]) * (1 - expit(v[i]))
      for j in range(i + 1):
          J[i, j] = sp * (1 if j == 0 else exp(y[j]))
  print(float(log(abs(det(J)))))  # -51.328128121070321

Closes #5088 (last remaining item).
@ricardoV94 ricardoV94 force-pushed the clean-pytensor-imports branch from c3a9400 to d9c48b8 Compare April 10, 2026 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants