Skip to content
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

Circuit.from_ir not supporting observables on physical qubits #854

Open
yitchen-tim opened this issue Jan 16, 2024 · 2 comments
Open

Circuit.from_ir not supporting observables on physical qubits #854

yitchen-tim opened this issue Jan 16, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@yitchen-tim
Copy link
Contributor

Describe the bug
When the openqasm IR includes #pragma braket result expectation z($0) @ z($1), Circuit.from_ir throws error line 1:28 no viable alternative at input 'z($0'.

This error only happens to physical qubits. When using observables on virtual qubits, there is no error.

To reproduce

qasm_program = """
OPENQASM 3.0;
#pragma braket verbatim
box{
gpi2(6.283185307179586) $1;
gpi2(6.283185307179586) $0;
ms(4.397592653589793, 0.0) $0, $1;
}
#pragma braket result expectation z($0) @ z($1)
"""

circuit = Circuit.from_ir(qasm_program)
print(circuit)

Expected behavior
Returns a Braket circuit that represents the QASM program above.

Screenshots or logs

line 1:28 no viable alternative at input 'z($0'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[62], line 12
      1 qasm_program = """
      2 OPENQASM 3.0;
      3 #pragma braket verbatim
   (...)
      9 #pragma braket result expectation z($0) @ z($1)
     10 """
---> 12 circuit = Circuit.from_ir(qasm_program)
     13 print(circuit)

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/circuits/circuit.py:1175, in Circuit.from_ir(source, inputs)
   1172     source = source.source
   1173 from braket.circuits.braket_program_context import BraketProgramContext
-> 1175 return Interpreter(BraketProgramContext()).build_circuit(
   1176     source=source,
   1177     inputs=inputs,
   1178     is_file=False,
   1179 )

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/interpreter.py:130, in Interpreter.build_circuit(self, source, inputs, is_file)
    126 def build_circuit(
    127     self, source: str, inputs: Optional[dict[str, io_type]] = None, is_file: bool = False
    128 ) -> Circuit:
    129     """Interpret an OpenQASM program and build a Circuit IR."""
--> 130     return self.run(source, inputs, is_file).circuit

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/interpreter.py:145, in Interpreter.run(self, source, inputs, is_file)
    143 program = parse(source)
    144 self._uses_advanced_language_features = False
--> 145 self.visit(program)
    146 if self._uses_advanced_language_features:
    147     self.logger.warning(
    148         "This program uses OpenQASM language features that may "
    149         "not be supported on QPUs or on-demand simulators."
    150     )

File ~/miniconda/lib/python3.10/functools.py:926, in singledispatchmethod.__get__.<locals>._method(*args, **kwargs)
    924 def _method(*args, **kwargs):
    925     method = self.dispatcher.dispatch(args[0].__class__)
--> 926     return method.__get__(obj, cls)(*args, **kwargs)

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/interpreter.py:172, in Interpreter._(self, node)
    170 @visit.register
    171 def _(self, node: Program) -> None:
--> 172     self.visit(node.statements)

File ~/miniconda/lib/python3.10/functools.py:926, in singledispatchmethod.__get__.<locals>._method(*args, **kwargs)
    924 def _method(*args, **kwargs):
    925     method = self.dispatcher.dispatch(args[0].__class__)
--> 926     return method.__get__(obj, cls)(*args, **kwargs)

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/interpreter.py:168, in Interpreter._(self, node_list)
    165 @visit.register
    166 def _(self, node_list: list) -> list[QASMNode]:
    167     """Generic visit function for a list of AST nodes"""
--> 168     return [n for n in [self.visit(node) for node in node_list] if n is not None]

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/interpreter.py:168, in <listcomp>(.0)
    165 @visit.register
    166 def _(self, node_list: list) -> list[QASMNode]:
    167     """Generic visit function for a list of AST nodes"""
--> 168     return [n for n in [self.visit(node) for node in node_list] if n is not None]

File ~/miniconda/lib/python3.10/functools.py:926, in singledispatchmethod.__get__.<locals>._method(*args, **kwargs)
    924 def _method(*args, **kwargs):
    925     method = self.dispatcher.dispatch(args[0].__class__)
--> 926     return method.__get__(obj, cls)(*args, **kwargs)

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/interpreter.py:543, in Interpreter._(self, node)
    541 @visit.register
    542 def _(self, node: Pragma) -> None:
--> 543     parsed = self.context.parse_pragma(node.command)
    544     if node.command.startswith("braket result"):
    545         if not parsed:

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/program_context.py:444, in AbstractProgramContext.parse_pragma(self, pragma_body)
    437 def parse_pragma(self, pragma_body: str):
    438     """
    439     Parse pragma
    440 
    441     Args:
    442         pragma_body (str): The body of the pragma statement.
    443     """
--> 444     return parse_braket_pragma(pragma_body, self.qubit_mapping)

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/parser/braket_pragmas.py:216, in parse_braket_pragma(pragma_body, qubit_table)
    214 parser = BraketPragmasParser(stream)
    215 tree = parser.braketPragma()
--> 216 visited = BraketPragmaNodeVisitor(qubit_table).visit(tree)
    217 return visited

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/antlr4/tree/Tree.py:34, in ParseTreeVisitor.visit(self, tree)
     33 def visit(self, tree):
---> 34     return tree.accept(self)

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/parser/generated/BraketPragmasParser.py:861, in BraketPragmasParser.BraketPragmaContext.accept(self, visitor)
    859 def accept(self, visitor:ParseTreeVisitor):
    860     if hasattr( visitor, "visitBraketPragma" ):
--> 861         return visitor.visitBraketPragma(self)
    862     else:
    863         return visitor.visitChildren(self)

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/parser/generated/BraketPragmasParserVisitor.py:14, in BraketPragmasParserVisitor.visitBraketPragma(self, ctx)
     13 def visitBraketPragma(self, ctx:BraketPragmasParser.BraketPragmaContext):
---> 14     return self.visitChildren(ctx)

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/antlr4/tree/Tree.py:44, in ParseTreeVisitor.visitChildren(self, node)
     41         return result
     43     c = node.getChild(i)
---> 44     childResult = c.accept(self)
     45     result = self.aggregateResult(result, childResult)
     47 return result

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/parser/generated/BraketPragmasParser.py:1226, in BraketPragmasParser.BraketResultPragmaContext.accept(self, visitor)
   1224 def accept(self, visitor:ParseTreeVisitor):
   1225     if hasattr( visitor, "visitBraketResultPragma" ):
-> 1226         return visitor.visitBraketResultPragma(self)
   1227     else:
   1228         return visitor.visitChildren(self)

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/parser/generated/BraketPragmasParserVisitor.py:39, in BraketPragmasParserVisitor.visitBraketResultPragma(self, ctx)
     38 def visitBraketResultPragma(self, ctx:BraketPragmasParser.BraketResultPragmaContext):
---> 39     return self.visitChildren(ctx)

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/antlr4/tree/Tree.py:44, in ParseTreeVisitor.visitChildren(self, node)
     41         return result
     43     c = node.getChild(i)
---> 44     childResult = c.accept(self)
     45     result = self.aggregateResult(result, childResult)
     47 return result

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/parser/generated/BraketPragmasParser.py:1290, in BraketPragmasParser.ResultTypeContext.accept(self, visitor)
   1288 def accept(self, visitor:ParseTreeVisitor):
   1289     if hasattr( visitor, "visitResultType" ):
-> 1290         return visitor.visitResultType(self)
   1291     else:
   1292         return visitor.visitChildren(self)

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/parser/generated/BraketPragmasParserVisitor.py:44, in BraketPragmasParserVisitor.visitResultType(self, ctx)
     43 def visitResultType(self, ctx:BraketPragmasParser.ResultTypeContext):
---> 44     return self.visitChildren(ctx)

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/antlr4/tree/Tree.py:44, in ParseTreeVisitor.visitChildren(self, node)
     41         return result
     43     c = node.getChild(i)
---> 44     childResult = c.accept(self)
     45     result = self.aggregateResult(result, childResult)
     47 return result

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/parser/generated/BraketPragmasParser.py:1867, in BraketPragmasParser.ObservableResultTypeContext.accept(self, visitor)
   1865 def accept(self, visitor:ParseTreeVisitor):
   1866     if hasattr( visitor, "visitObservableResultType" ):
-> 1867         return visitor.visitObservableResultType(self)
   1868     else:
   1869         return visitor.visitChildren(self)

File ~/virtual_envs/qpu-onboard/lib/python3.10/site-packages/braket/default_simulator/openqasm/parser/braket_pragmas.py:98, in BraketPragmaNodeVisitor.visitObservableResultType(self, ctx)
     92 result_type = ctx.observableResultTypeName().getText()
     93 observable_result_type_map = {
     94     "expectation": Expectation,
     95     "sample": Sample,
     96     "variance": Variance,
     97 }
---> 98 observables, targets = self.visit(ctx.observable())
     99 obs = observable_result_type_map[result_type](targets=targets, observable=observables)
    100 return obs

TypeError: cannot unpack non-iterable NoneType object

System information
A description of your system. Please provide:
amazon-braket-algorithm-library 1.2.0
amazon-braket-default-simulator 1.20.1
amazon-braket-pennylane-plugin 1.12.2
amazon-braket-schemas 1.19.1.post0
amazon-braket-sdk 1.65.2.dev0
Python version**: 3.10.9

@yitchen-tim yitchen-tim added the bug Something isn't working label Jan 16, 2024
@yitchen-tim yitchen-tim changed the title `Circuit.from_ir1 not supporting observables on physical qubits Circuit.from_ir not supporting observables on physical qubits Jan 16, 2024
@speller26
Copy link
Member

Physical qubits and verbatim boxes are not currently supported; we'll need to add the stubs to the default simulator and implement them here.

@laurencap
Copy link
Contributor

laurencap commented Jan 29, 2024

@speller26 Should we update this issue from bug to enhancement? Edit: or, is there a way to improve the error message?

@guomanmin guomanmin added enhancement New feature or request and removed bug Something isn't working labels Mar 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants