Beispiel #1
0
    def on(self, params: List[float], args: List[List[ops.Qid]],
           lineno: int) -> Iterable[ops.Operation]:
        self._validate_args(args, lineno)
        self._validate_params(params, lineno)

        reg_sizes = np.unique([len(reg) for reg in args])
        if len(reg_sizes) > 2 or (len(reg_sizes) > 1 and reg_sizes[0] != 1):
            raise QasmException("Non matching quantum registers of length {} "
                                "at line {}".format(reg_sizes, lineno))

        # the actual gate we'll apply the arguments to might be a parameterized
        # or non-parametrized gate
        final_gate = (self.cirq_gate if isinstance(self.cirq_gate, ops.Gate)
                      else self.cirq_gate(params))  # type: ops.Gate
        # OpenQASM gates can be applied on single qubits and qubit registers.
        # We represent single qubits as registers of size 1.
        # Based on the OpenQASM spec (https://arxiv.org/abs/1707.03429),
        # single qubit arguments can be mixed with qubit registers.
        # Given quantum registers of length reg_size and single qubits are both
        # used as arguments, we generate reg_size GateOperations via iterating
        # through each qubit of the registers 0 to n-1 and use the same one
        # qubit from the "single-qubit registers" for each operation.
        op_qubits = cast(Sequence[Sequence[ops.Qid]],
                         functools.reduce(np.broadcast, args))
        for qubits in op_qubits:
            if isinstance(qubits, ops.Qid):
                yield final_gate.on(qubits)
            elif len(np.unique(qubits)) < len(qubits):
                raise QasmException("Overlapping qubits in arguments"
                                    " at line {}".format(lineno))
            else:
                yield final_gate.on(*qubits)
Beispiel #2
0
    def p_error(self, p):
        if p is None:
            raise QasmException('Unexpected end of file')

        raise QasmException(f"""Syntax error: '{p.value}'
{self.debug_context(p)}
at line {p.lineno}, column {self.find_column(p)}""")
Beispiel #3
0
    def p_error(self, p):
        if p is None:
            raise QasmException('Unexpected end of file')

        raise QasmException("""Syntax error: '{}'
{}
at line {}, column {}""".format(p.value, self.debug_context(p), p.lineno,
                                self.find_column(p)))
Beispiel #4
0
 def p_new_reg(self, p):
     """new_reg : QREG ID '[' NATURAL_NUMBER ']' ';'
     | CREG ID '[' NATURAL_NUMBER ']' ';'"""
     name, length = p[2], p[4]
     if name in self.qregs.keys() or name in self.cregs.keys():
         raise QasmException(f"{name} is already defined at line {p.lineno(2)}")
     if length == 0:
         raise QasmException(f"Illegal, zero-length register '{name}' at line {p.lineno(4)}")
     if p[1] == "qreg":
         self.qregs[name] = length
     else:
         self.cregs[name] = length
     p[0] = (name, length)
Beispiel #5
0
 def _validate_params(self, params: List[float], lineno: int):
     if len(params) != self.num_params:
         raise QasmException(
             "{} takes {} parameter(s), got: {}, at line {}".format(
                 self.qasm_gate, self.num_params, len(params), lineno
             )
         )
Beispiel #6
0
    def p_classical_arg_register(self, p):
        """carg : ID"""
        reg = p[1]
        if reg not in self.cregs.keys():
            raise QasmException(f'Undefined classical register "{reg}" at line {p.lineno(1)}')

        p[0] = [self.make_name(idx, reg) for idx in range(self.cregs[reg])]
Beispiel #7
0
 def p_format(self, p):
     """format : FORMAT_SPEC"""
     if p[1] != "2.0":
         raise QasmException(
             "Unsupported OpenQASM version: {}, "
             "only 2.0 is supported currently by Cirq".format(p[1])
         )
Beispiel #8
0
 def p_expr_function_call(self, p):
     """expr : ID '(' expr ')'"""
     func = p[1]
     if func not in self.functions.keys():
         raise QasmException(
             f"Function not recognized: '{func}' at line {p.lineno(1)}")
     p[0] = self.functions[func](p[3])
Beispiel #9
0
    def p_classical_arg_bit(self, p):
        """carg : ID '[' NATURAL_NUMBER ']' """
        reg = p[1]
        idx = p[3]
        arg_name = self.make_name(idx, reg)
        if reg not in self.cregs.keys():
            raise QasmException('Undefined classical register "{}" '
                                'at line {}'.format(reg, p.lineno(1)))

        size = self.cregs[reg]
        if idx >= size:
            raise QasmException('Out of bounds bit index {} '
                                'on classical register {} of size {} '
                                'at line {}'.format(idx, reg, size,
                                                    p.lineno(1)))
        p[0] = [arg_name]
Beispiel #10
0
 def p_quantum_arg_bit(self, p):
     """qarg : ID '[' NATURAL_NUMBER ']' """
     reg = p[1]
     idx = p[3]
     arg_name = self.make_name(idx, reg)
     if reg not in self.qregs.keys():
         raise QasmException('Undefined quantum register "{}" '
                             'at line {}'.format(reg, p.lineno(1)))
     size = self.qregs[reg]
     if idx >= size:
         raise QasmException('Out of bounds qubit index {} '
                             'on register {} of size {} '
                             'at line {}'.format(idx, reg, size,
                                                 p.lineno(1)))
     if arg_name not in self.qubits.keys():
         self.qubits[arg_name] = NamedQubit(arg_name)
     p[0] = [self.qubits[arg_name]]
Beispiel #11
0
 def _resolve_gate_operation(self, args: List[List[ops.Qid]], gate: str,
                             p: Any, params: List[float]):
     gate_set = (self.basic_gates if not self.qelibinc else self.all_gates)
     if gate not in gate_set.keys():
         msg = 'Unknown gate "{}" at line {}{}'.format(
             gate, p.lineno(1), ", did you forget to include qelib1.inc?"
             if not self.qelibinc else "")
         raise QasmException(msg)
     p[0] = gate_set[gate].on(args=args, params=params, lineno=p.lineno(1))
Beispiel #12
0
 def _resolve_gate_operation(self, args: List[List[ops.Qid]], gate: str,
                             p: Any, params: List[float]):
     if gate not in self.basic_gates.keys():
         raise QasmException('Unknown gate "{}" at line {}, '
                             'maybe you forgot to include '
                             'the standard qelib1.inc?'.format(
                                 gate, p.lineno(1)))
     p[0] = self.basic_gates[gate].on(args=args,
                                      params=params,
                                      lineno=p.lineno(1))
Beispiel #13
0
 def p_quantum_arg_register(self, p):
     """qarg : ID"""
     reg = p[1]
     if reg not in self.qregs.keys():
         raise QasmException(f'Undefined quantum register "{reg}" at line {p.lineno(1)}')
     qubits = []
     for idx in range(self.qregs[reg]):
         arg_name = self.make_name(idx, reg)
         if arg_name not in self.qubits.keys():
             self.qubits[arg_name] = NamedQubit(arg_name)
         qubits.append(self.qubits[arg_name])
     p[0] = qubits
Beispiel #14
0
 def p_new_reg(self, p):
     """new_reg : QREG ID '[' NATURAL_NUMBER ']' ';'
                 | CREG ID '[' NATURAL_NUMBER ']' ';'"""
     name, length = p[2], p[4]
     if name in self.qregs.keys() or name in self.cregs.keys():
         raise QasmException("{} is already defined "
                             "at line {}".format(name, p.lineno(2)))
     if p[1] == "qreg":
         self.qregs[name] = length
     else:
         self.cregs[name] = length
     p[0] = (name, length)
Beispiel #15
0
    def p_measurement(self, p):
        """measurement : MEASURE qarg ARROW carg ';'"""
        qreg = p[2]
        creg = p[4]

        if len(qreg) != len(creg):
            raise QasmException(
                'mismatched register sizes {} -> {} for measurement '
                'at line {}'.format(len(qreg), len(creg), p.lineno(1)))

        p[0] = [
            ops.MeasurementGate(num_qubits=1, key=creg[i]).on(qreg[i])
            for i in range(len(qreg))
        ]
Beispiel #16
0
 def t_error(self, t):
     raise QasmException("Illegal character '{}' at line {}".format(
         t.value[0], t.lineno))
Beispiel #17
0
 def t_error(self, t):
     raise QasmException(f"Illegal character '{t.value[0]}' at line {t.lineno}")
Beispiel #18
0
 def _validate_args(self, args: List[List[ops.Qid]], lineno: int):
     if len(args) != self.num_args:
         raise QasmException(
             "{} only takes {} arg(s) (qubits and/or registers), "
             "got: {}, at line {}".format(self.qasm_gate, self.num_args,
                                          len(args), lineno))
Beispiel #19
0
 def p_qasm_no_format_specified_error(self, p):
     """qasm : QELIBINC
             | circuit """
     if self.supported_format is False:
         raise QasmException("Missing 'OPENQASM 2.0;' statement")