Skip to content

Commit 465fcc5

Browse files
authored
Merge branch 'main' into bloq_to_quirk
2 parents 08e21cd + 1ee71bf commit 465fcc5

143 files changed

Lines changed: 12921 additions & 3564 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gemini/config.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Summary: configure Gemini Code Assist (https://codeassist.google/).
16+
# See https://github.com/marketplace/gemini-code-assist for more info.
17+
18+
have_fun: false
19+
code_review:
20+
disable: false
21+
comment_severity_threshold: HIGH
22+
max_review_comments: -1
23+
pull_request_opened:
24+
help: false
25+
summary: false
26+
code_review: true
27+
include_drafts: false
28+
ignore_patterns: []

dev_tools/conf/.pylintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
load-plugins=pylint.extensions.docstyle,pylint.extensions.docparams,pylint_copyright_checker
33
max-line-length=100
44
ignore-patterns=.*_pb2\.py
5+
ignore=.venv
56
output-format=colorized
67
score=no
78
reports=no

dev_tools/conf/mypy.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[mypy]
22
show_error_codes = true
3-
plugins = duet.typing, numpy.typing.mypy_plugin
3+
plugins = duet.typing
44
allow_redefinition = true
55
check_untyped_defs = true
66

dev_tools/dump-bloq-manifest.py

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""
16+
Script to dump a manifest of all bloq classes and bloq examples.
17+
18+
This script finds all Bloq classes and examples in the library, serializes the examples
19+
to their objectstring representation, and writes the list of class names and
20+
example objectstrings to `qualtran/bloqs/manifest.py`.
21+
22+
See `qualtran.l1.load_objectstring()` to load bloq objects from these strings.
23+
"""
24+
25+
from functools import cached_property
26+
from typing import List, Tuple
27+
28+
from attrs import frozen
29+
from qualtran_dev_tools.bloq_finder import get_bloq_classes, get_bloq_examples
30+
from qualtran_dev_tools.git_tools import get_git_root
31+
32+
from qualtran import Bloq
33+
from qualtran.l1 import eval_cvalue_node, parse_objectstring, to_cobject_node
34+
from qualtran.l1.nodes import CArgNode, CObjectNode, LiteralNode
35+
36+
MAXLEN = 300
37+
"""If the objectstring is too long, we make the executive decision to truncate it."""
38+
39+
COPYRIGHT_NOTICE = """# Copyright 2026 Google LLC
40+
#
41+
# Licensed under the Apache License, Version 2.0 (the "License");
42+
# you may not use this file except in compliance with the License.
43+
# You may obtain a copy of the License at
44+
#
45+
# https://www.apache.org/licenses/LICENSE-2.0
46+
#
47+
# Unless required by applicable law or agreed to in writing, software
48+
# distributed under the License is distributed on an "AS IS" BASIS,
49+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
50+
# See the License for the specific language governing permissions and
51+
# limitations under the License."""
52+
53+
54+
@frozen
55+
class BloqExampleListItem:
56+
"""Formatting a bloq example and its serialized form.
57+
58+
Attributes:
59+
bloq: The bloq instance from the example.
60+
bloq_example_name: The name of the bloq example.
61+
cobject_node: The CObjectNode representing the serialized bloq.
62+
"""
63+
64+
bloq: Bloq
65+
bloq_example_name: str
66+
cobject_node: CObjectNode
67+
68+
@cached_property
69+
def objectstring(self) -> str:
70+
"""Returns the canonical string representation of the CObjectNode."""
71+
return self.cobject_node.canonical_str()
72+
73+
def maybe_commented_out(self, be_column_width: int = 30) -> Tuple[str, str, str]:
74+
"""Generates a string representation for the manifest, potentially commented out.
75+
76+
This method checks if the object string is too long, unparsable, unloadable, or
77+
if the re-loaded bloq is unequal to the original. If any of these conditions are met,
78+
it returns a commented-out string with a reason. Otherwise, it returns the
79+
executable string representation.
80+
81+
Args:
82+
be_column_width: The width of the column for the bloq example name for nicer formatting.
83+
84+
Returns:
85+
manifest_entry_str: The string to be written to the manifest (possibly commented out).
86+
reason: A reason string if it was commented out (empty otherwise).
87+
reason_details: Detailed error message if applicable (empty otherwise).
88+
"""
89+
quoted_be = f"'{self.bloq_example_name}',"
90+
be = f'{quoted_be:{be_column_width}}'
91+
be2 = f'{quoted_be:{be_column_width+2}}'
92+
93+
if len(self.objectstring) > MAXLEN:
94+
trunc = repr(self.objectstring)[:120] + '...'
95+
return f'# ({be}{trunc}', 'too long', ''
96+
97+
try:
98+
node = parse_objectstring(self.objectstring)
99+
except Exception as e: # pylint: disable=broad-except
100+
return f'# ({be}{self.objectstring!r}),', 'unparsable', str(e)
101+
102+
try:
103+
bloq = eval_cvalue_node(node, safe=False)
104+
except Exception as e: # pylint: disable=broad-except
105+
return f'# ({be}{self.objectstring!r}),', 'unloadable', str(e)
106+
107+
if bloq != self.bloq:
108+
return f'# ({be}{self.objectstring!r}),', 'unequal', ''
109+
110+
return f'({be2}{self.objectstring!r}),', '', ''
111+
112+
113+
def main():
114+
"""Main entry point for the script.
115+
116+
Finds all bloq classes and examples, processes them, and writes the
117+
`BLOQ_CLASS_NAMES` and `BLOQ_EXAMPLE_OBJECTSTRINGS` lists to
118+
`qualtran/bloqs/manifest.py`.
119+
"""
120+
bcs = get_bloq_classes()
121+
names = sorted(bc._class_name_in_pkg_() for bc in bcs)
122+
123+
bes = get_bloq_examples()
124+
items: List[BloqExampleListItem] = []
125+
for be in bes:
126+
bloq = be.make()
127+
try:
128+
cobject_node = to_cobject_node(bloq)
129+
assert isinstance(cobject_node, CObjectNode)
130+
except Exception as e: # pylint: disable=broad-except
131+
cobject_node = CObjectNode(
132+
name=bloq._class_name_in_pkg_(), cargs=[CArgNode(None, LiteralNode(str(e)))]
133+
)
134+
items.append(
135+
BloqExampleListItem(bloq=bloq, bloq_example_name=be.name, cobject_node=cobject_node)
136+
)
137+
138+
items = sorted(items, key=lambda x: x.objectstring)
139+
include_commented_out = True
140+
be_objectstrings = []
141+
for item in items:
142+
serstr, reason, details = item.maybe_commented_out()
143+
144+
if (not reason) or include_commented_out:
145+
be_objectstrings.append(serstr)
146+
147+
if reason:
148+
reason = f'({reason})'
149+
print(f"Skipping {reason:20s} {serstr}")
150+
151+
if details:
152+
print(f' {"":20s} ->', details)
153+
154+
reporoot = get_git_root()
155+
with (reporoot / 'qualtran/bloqs/manifest.py').open('w') as f:
156+
f.write(COPYRIGHT_NOTICE)
157+
f.write('\n\n')
158+
f.write('# This file is autogenerated\n')
159+
f.write('# See dev_tools/dump-bloq-manifest.py\n')
160+
f.write('# fmt: off\n\n')
161+
f.write('BLOQ_CLASS_NAMES = [\n')
162+
f.write('\n'.join([f' "{name}",' for name in names]))
163+
f.write('\n]\n')
164+
165+
f.write('\n')
166+
167+
f.write('BLOQ_EXAMPLE_OBJECTSTRINGS = [\n')
168+
f.write('\n'.join([f' {objstr}' for objstr in be_objectstrings]))
169+
f.write('\n]\n')
170+
171+
172+
if __name__ == '__main__':
173+
main()

dev_tools/qualtran_dev_tools/make_reference_docs/_make.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,12 @@
7878
]
7979
MINIMAL = True
8080

81-
DEFINED_IN_CONTAINER_EXCEPTIONS = ['qualtran.dtype', 'qualtran.exception', 'qualtran.cirq_interop']
81+
DEFINED_IN_CONTAINER_EXCEPTIONS = [
82+
'qualtran.dtype',
83+
'qualtran.exception',
84+
'qualtran.cirq_interop',
85+
'qualtran.l1.nodes',
86+
]
8287

8388

8489
def _get_all_aliases(obj: Union[griffe.Object, griffe.Alias]) -> Set[str]:

dev_tools/qualtran_dev_tools/notebook_specs.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,13 @@
889889
qualtran.bloqs.optimization.k_xor_sat.kikuchi_block_encoding._KIKUCHI_HAMILTONIAN_DOC
890890
],
891891
),
892+
NotebookSpecV2(
893+
title='Algorithm: Planted Noisy kXOR',
894+
module=qualtran.bloqs.optimization.k_xor_sat.planted_noisy_kxor,
895+
bloq_specs=[
896+
qualtran.bloqs.optimization.k_xor_sat.planted_noisy_kxor._PLANTED_NOISY_KXOR_DOC
897+
],
898+
),
892899
]
893900

894901
BOOKKEEPING: List[NotebookSpecV2] = [

0 commit comments

Comments
 (0)