Description
Description:
When you instantiate certain Bloq subclasses with Sympy symbols for register widths (e.g.)
StatePreparationAliasSampling.from_n_coeff(L, lam, precision=eps)
the call to decompose_bloq() immediately raises
DecomposeTypeError("bitsize must be a concrete value")
because each of these Bloq classes contains a guard like:
if not isinstance(self.bitsize, int):
raise DecomposeTypeError("bitsize must be a concrete value")
This affects many Bloqs (e.g. LessThanEqual
, QROM
, CSwap
, etc.) and prevents any symbolic-parameter subtree from ever being expanded when you convert to QREF + GraphViz. All you ever see is a monolithic leaf.
There is a private _decompose_from_build_composite_bloq()
that builds a CompositeBloq
via the call-graph, but it still runs the same per-class guards, so it also refuses on symbolic bitsizes.
Why the “obvious” fixes don’t work
-
Centralizing dual-fallback in the QREF importer
We could catchDecomposeTypeError
andcall _decompose_from_build_composite_bloq()
instead—but that builder itself enforces the sameisinstance(bitsize, int)
checks, so symbolic widths are still rejected. -
Using
from_callgraph=True
There is already abloq_to_qref(..., from_callgraph=True)
path, but it only reconstructs a flat call-graph of Bloqs. It does not produce real port definitions or connection wiring in the resultingRoutineV1
, soto_graphviz
on that schema loses all topology.
Minimal repro
import sympy
from qualtran.bloqs.state_preparation import StatePreparationAliasSampling
L, lam, eps = sympy.symbols("L lam eps")
alias = StatePreparationAliasSampling.from_n_coeff(L, lam, precision=eps)
cb = alias.decompose_bloq() # CompositeBloq with 5 leaves
for inst in cb.bloq_instances:
inst.bloq.decompose_bloq() # always raises DecomposeTypeError
Related
MR #1643 adds a dual-fallback for numeric Bloqs, but it still fails for symbolic cases because of the per-class guards.
Tagging @mstechly