diff --git a/quafu/circuits/quantum_circuit.py b/quafu/circuits/quantum_circuit.py index 28286b7d..18aed16e 100644 --- a/quafu/circuits/quantum_circuit.py +++ b/quafu/circuits/quantum_circuit.py @@ -492,7 +492,7 @@ def to_openqasm(self) -> str: valid_gates = QuantumGate.gate_classes #TODO:include instruction futher qasm = 'OPENQASM 2.0;\ninclude "qelib1.inc";\n' qasm += "qreg q[%d];\n" % self.num - qasm += "creg meas[%d];\n" % len(self.measures) + qasm += "creg meas[%d];\n" % self.cbits_num for gate in self.gates: if gate.name.lower() in valid_gates: qasm += gate.to_qasm() + ";\n" diff --git a/quafu/qfasm/qelib1.inc b/quafu/qfasm/qelib1.inc index 24b9b2a3..bc13f3aa 100644 --- a/quafu/qfasm/qelib1.inc +++ b/quafu/qfasm/qelib1.inc @@ -267,3 +267,24 @@ gate c4x a,b,c,d,e c3x a,b,c,d; c3sqrtx a,b,c,e; } + +// add gate supported by pyquafu +// cnot +gate cnot c,t {} +// mcx mcy mcz need more support in parser +// ryy +gate ryy(theta) a,b {} +// cs +gate cs a,b {} +// ct +gate ct a,b {} +// sy +gate sy a {} +// w +gate w a {} +// sw +gate sw a {} +// Toffoli +gate toffoli a,b,c {} +// Fredkin +gate fredkin a,b,c {} diff --git a/quafu/qfasm/qfasm_parser.py b/quafu/qfasm/qfasm_parser.py index ab793789..f3dc44c7 100644 --- a/quafu/qfasm/qfasm_parser.py +++ b/quafu/qfasm/qfasm_parser.py @@ -70,6 +70,7 @@ def __init__(self, filepath: str = None, debug=False): self.stdgate = list(gate_classes.keys()) # extent keyword(the ) self.stdgate.extend(["U", "CX"]) + self.mulctrl = ["mcx", "mcz", "mcy"] self.parser = yacc.yacc(module=self, debug=debug) # when there is reset/op after measure/if, set to false self.executable_on_backend = True @@ -148,11 +149,7 @@ def updateSymtab(self, symtabnode: SymtabNode): def handle_gateins(self, gateins: GateInstruction): gate_list = [] # end of recurse - if gateins.name in self.stdgate and gateins.name not in [ - "reset", - "barrier", - "measure", - ]: + if gateins.name in self.stdgate and gateins.name not in self.nuop: args = [] # add qubits to args, it's might be a qubit or a qreg for qarg in gateins.qargs: @@ -184,10 +181,13 @@ def handle_gateins(self, gateins: GateInstruction): # if it's U or CX if gateins.name == "CX": gateins.name = "cx" - if gateins.name == "U": + gate_list.append(gate_classes[gateins.name](*oneargs)) + elif gateins.name == "U": gate_list.append(gate_classes["rz"](*[*oneargs, gateins.cargs[2]])) gate_list.append(gate_classes["ry"](*[*oneargs, gateins.cargs[0]])) gate_list.append(gate_classes["rz"](*[*oneargs, gateins.cargs[1]])) + elif gateins.name in self.mulctrl: + gate_list.append(gate_classes[gateins.name](oneargs[:-1], oneargs[-1])) else: # add carg to args if there is if gateins.cargs is not None and len(gateins.cargs) > 0: @@ -373,7 +373,7 @@ def check_measure_bit(self, gateins: GateInstruction): def check_qargs(self, gateins: GateInstruction): # check gatename declared qargslist = [] - if gateins.name not in self.nuop: + if gateins.name not in self.nuop and gateins.name not in self.mulctrl: if gateins.name not in self.global_symtab: raise ParserError( f"The gate {gateins.name} is undefined at line {gateins.lineno} file {gateins.filename}" @@ -419,7 +419,7 @@ def check_qargs(self, gateins: GateInstruction): def check_cargs(self, gateins: GateInstruction): # check that cargs belongs to unary (they must be int or float) # cargs is different from CREG - if gateins.name not in self.nuop: + if gateins.name not in self.nuop and gateins.name not in self.mulctrl: if gateins.name not in self.global_symtab: raise ParserError( f"The gate {gateins.name} is undefined at line {gateins.lineno} file {gateins.filename}"