@@ -924,16 +924,24 @@ def test_standard_gates_wrong_params_error(qasm_gate: str, num_params: int):
924
924
]
925
925
926
926
927
+ # Mapping of two-qubit gates and `num_params`
928
+ two_qubit_param_gates = {
929
+ ('cu1' , cirq .ControlledGate (QasmUGate (0 , 0 , 0.1 / np .pi ))): 1 ,
930
+ ('cu3' , cirq .ControlledGate (QasmUGate (0.1 / np .pi , 0.2 / np .pi , 0.3 / np .pi ))): 3 ,
931
+ ('crz' , cirq .ControlledGate (cirq .rz (0.1 ))): 1 ,
932
+ }
933
+
934
+
927
935
@pytest .mark .parametrize ('qasm_gate,cirq_gate' , two_qubit_gates )
928
936
def test_two_qubit_gates (qasm_gate : str , cirq_gate : cirq .testing .TwoQubitGate ):
929
937
qasm = f"""
930
- OPENQASM 2.0;
931
- include "qelib1.inc";
932
- qreg q1[2];
933
- qreg q2[2];
934
- { qasm_gate } q1[0], q1[1];
935
- { qasm_gate } q1, q2[0];
936
- { qasm_gate } q2, q1;
938
+ OPENQASM 2.0;
939
+ include "qelib1.inc";
940
+ qreg q1[2];
941
+ qreg q2[2];
942
+ { qasm_gate } q1[0], q1[1];
943
+ { qasm_gate } q1, q2[0];
944
+ { qasm_gate } q2, q1;
937
945
"""
938
946
parser = QasmParser ()
939
947
@@ -961,11 +969,85 @@ def test_two_qubit_gates(qasm_gate: str, cirq_gate: cirq.testing.TwoQubitGate):
961
969
assert parsed_qasm .qregs == {'q1' : 2 , 'q2' : 2 }
962
970
963
971
964
- @pytest .mark .parametrize ('qasm_gate' , [g [0 ] for g in two_qubit_gates ])
972
+ @pytest .mark .parametrize (
973
+ 'qasm_gate,cirq_gate,num_params' ,
974
+ [
975
+ (gate_map [0 ], gate_map [1 ], num_param )
976
+ for gate_map , num_param in two_qubit_param_gates .items ()
977
+ ],
978
+ )
979
+ def test_two_qubit_param_gates (
980
+ qasm_gate : str , cirq_gate : cirq .testing .TwoQubitGate , num_params : int
981
+ ):
982
+ params = '(0.1, 0.2, 0.3)' if num_params == 3 else '(0.1)'
983
+ qasm = f"""
984
+ OPENQASM 2.0;
985
+ include "qelib1.inc";
986
+ qreg q1[2];
987
+ qreg q2[2];
988
+ { qasm_gate } { params } q1[0], q1[1];
989
+ { qasm_gate } { params } q1, q2[0];
990
+ { qasm_gate } { params } q2, q1;
991
+ """
992
+ parser = QasmParser ()
993
+
994
+ q1_0 = cirq .NamedQubit ('q1_0' )
995
+ q1_1 = cirq .NamedQubit ('q1_1' )
996
+ q2_0 = cirq .NamedQubit ('q2_0' )
997
+ q2_1 = cirq .NamedQubit ('q2_1' )
998
+
999
+ expected_circuit = cirq .Circuit ()
1000
+ expected_circuit .append (cirq_gate .on (q1_0 , q1_1 ))
1001
+ expected_circuit .append (cirq_gate .on (q1_0 , q2_0 ))
1002
+ expected_circuit .append (cirq_gate .on (q1_1 , q2_0 ))
1003
+ expected_circuit .append (cirq_gate .on (q2_0 , q1_0 ))
1004
+ expected_circuit .append (cirq_gate .on (q2_1 , q1_1 ))
1005
+ parsed_qasm = parser .parse (qasm )
1006
+
1007
+ assert parsed_qasm .supportedFormat
1008
+ assert parsed_qasm .qelib1Include
1009
+
1010
+ ct .assert_same_circuits (parsed_qasm .circuit , expected_circuit )
1011
+ assert parsed_qasm .qregs == {'q1' : 2 , 'q2' : 2 }
1012
+
1013
+
1014
+ @pytest .mark .parametrize (
1015
+ 'qasm_gate' , [g [0 ] for g in two_qubit_gates ] + [g [0 ] for g in two_qubit_param_gates .keys ()]
1016
+ )
1017
+ def test_two_qubit_gates_not_enough_qubits (qasm_gate : str ):
1018
+ if qasm_gate in ('cu1' , 'crz' ):
1019
+ qasm = f"""
1020
+ OPENQASM 2.0;
1021
+ include "qelib1.inc";
1022
+ qreg q[2];
1023
+ { qasm_gate } (0.1) q[0];
1024
+ """
1025
+ elif qasm_gate == 'cu3' :
1026
+ qasm = f"""
1027
+ OPENQASM 2.0;
1028
+ include "qelib1.inc";
1029
+ qreg q[2];
1030
+ { qasm_gate } (0.1, 0.2, 0.3) q[0];
1031
+ """
1032
+ else :
1033
+ qasm = f"""
1034
+ OPENQASM 2.0;
1035
+ include "qelib1.inc";
1036
+ qreg q[2];
1037
+ { qasm_gate } q[0];
1038
+ """
1039
+
1040
+ parser = QasmParser ()
1041
+
1042
+ with pytest .raises (QasmException , match = rf".*{ qasm_gate } .* takes 2 arg\(s\).*got.*1.*line 5" ):
1043
+ parser .parse (qasm )
1044
+
1045
+
1046
+ @pytest .mark .parametrize ('qasm_gate' , [g [0 ] for g in two_qubit_param_gates .keys ()])
965
1047
def test_two_qubit_gates_not_enough_args (qasm_gate : str ):
966
1048
qasm = f"""
967
- OPENQASM 2.0;
968
- include "qelib1.inc";
1049
+ OPENQASM 2.0;
1050
+ include "qelib1.inc";
969
1051
qreg q[2];
970
1052
{ qasm_gate } q[0];
971
1053
"""
@@ -976,19 +1058,27 @@ def test_two_qubit_gates_not_enough_args(qasm_gate: str):
976
1058
parser .parse (qasm )
977
1059
978
1060
979
- @pytest .mark .parametrize ('qasm_gate' , [g [0 ] for g in two_qubit_gates ])
1061
+ @pytest .mark .parametrize (
1062
+ 'qasm_gate' , [g [0 ] for g in two_qubit_gates ] + [g [0 ] for g in two_qubit_param_gates .keys ()]
1063
+ )
980
1064
def test_two_qubit_gates_with_too_much_parameters (qasm_gate : str ):
1065
+ if qasm_gate in ('cu1' , 'cu3' , 'crz' ):
1066
+ num_params_needed = 3 if qasm_gate == 'cu3' else 1
1067
+ else :
1068
+ num_params_needed = 0
1069
+
981
1070
qasm = f"""
982
- OPENQASM 2.0;
983
- include "qelib1.inc";
984
- qreg q[2];
985
- { qasm_gate } (pi) q[0],q[1];
986
- """
1071
+ OPENQASM 2.0;
1072
+ include "qelib1.inc";
1073
+ qreg q[2];
1074
+ { qasm_gate } (pi, pi/2, pi/3, pi/4 ) q[0],q[1];
1075
+ """
987
1076
988
1077
parser = QasmParser ()
989
1078
990
1079
with pytest .raises (
991
- QasmException , match = rf".*{ qasm_gate } .* takes 0 parameter\(s\).*got.*1.*line 5"
1080
+ QasmException ,
1081
+ match = rf".*{ qasm_gate } *. takes { num_params_needed } parameter\(s\).*got.*4.*line 5" ,
992
1082
):
993
1083
parser .parse (qasm )
994
1084
0 commit comments