Skip to content

Commit

Permalink
Add ECR gate support to aer simulators (Qiskit#1674)
Browse files Browse the repository at this point in the history
* Add ECR gate support to aer simulators

This commit adds support for the ECR (echo cross resonance) gate as
described in [1] and [2] to aer. This is an entangling gate used on
some IBM backends and being able for aer to simulate is import to be
able to simulate those backends. Support for the gate is added to the
density matrix, statvector, super operator, and unitary simulators.

[1] https://arxiv.org/abs/2008.08571
[2] https://qiskit.org/documentation/stubs/qiskit.circuit.library.ECRGate.html

* Fix matrix definition

* Add tests

Co-authored-by: Hiroshi Horii <[email protected]>
  • Loading branch information
mtreinish and hhorii committed Dec 2, 2022
1 parent 5aeadd5 commit ca8bd21
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 20 deletions.
7 changes: 4 additions & 3 deletions qiskit_aer/backends/backend_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@
'rzz', 'rzx', 'ccx', 'cswap', 'mcx', 'mcy', 'mcz', 'mcsx',
'mcp', 'mcphase', 'mcu', 'mcu1', 'mcu2', 'mcu3', 'mcrx', 'mcry', 'mcrz',
'mcr', 'mcswap', 'unitary', 'diagonal', 'multiplexer',
'initialize', 'delay', 'pauli', 'mcx_gray'
'initialize', 'delay', 'pauli', 'mcx_gray', 'ecr'
]),
'density_matrix': sorted([
'u1', 'u2', 'u3', 'u', 'p', 'r', 'rx', 'ry', 'rz', 'id', 'x',
'y', 'z', 'h', 's', 'sdg', 'sx', 'sxdg', 't', 'tdg', 'swap', 'cx',
'cy', 'cz', 'cp', 'cu1', 'rxx', 'ryy', 'rzz', 'rzx', 'ccx',
'unitary', 'diagonal', 'delay', 'pauli',
'unitary', 'diagonal', 'delay', 'pauli', 'ecr',
]),
'matrix_product_state': sorted([
'u1', 'u2', 'u3', 'u', 'p', 'cp', 'cx', 'cy', 'cz', 'id', 'x', 'y', 'z', 'h', 's',
Expand All @@ -86,12 +86,13 @@
'rzz', 'rzx', 'ccx', 'cswap', 'mcx', 'mcy', 'mcz', 'mcsx',
'mcp', 'mcphase', 'mcu', 'mcu1', 'mcu2', 'mcu3', 'mcrx', 'mcry', 'mcrz',
'mcr', 'mcswap', 'unitary', 'diagonal', 'multiplexer', 'delay', 'pauli',
'ecr',
]),
'superop': sorted([
'u1', 'u2', 'u3', 'u', 'p', 'r', 'rx', 'ry', 'rz', 'id', 'x',
'y', 'z', 'h', 's', 'sdg', 'sx', 'sxdg', 't', 'tdg', 'swap', 'cx',
'cy', 'cz', 'cp', 'cu1', 'rxx', 'ryy',
'rzz', 'rzx', 'ccx', 'unitary', 'diagonal', 'delay', 'pauli'
'rzz', 'rzx', 'ccx', 'unitary', 'diagonal', 'delay', 'pauli', 'ecr',
])
}

Expand Down
4 changes: 2 additions & 2 deletions qiskit_aer/backends/qasm_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ class QasmSimulator(AerBackend):
'rzz', 'rzx', 'ccx', 'cswap', 'mcx', 'mcy', 'mcz', 'mcsx',
'mcp', 'mcphase', 'mcu', 'mcu1', 'mcu2', 'mcu3', 'mcrx', 'mcry', 'mcrz',
'mcr', 'mcswap', 'unitary', 'diagonal', 'multiplexer',
'initialize', 'delay', 'pauli', 'mcx_gray'
'initialize', 'delay', 'pauli', 'mcx_gray', 'ecr'
])

_DEFAULT_CUSTOM_INSTR = sorted([
Expand Down Expand Up @@ -601,7 +601,7 @@ def _method_basis_gates(self):
'u1', 'u2', 'u3', 'u', 'p', 'r', 'rx', 'ry', 'rz', 'id', 'x',
'y', 'z', 'h', 's', 'sdg', 'sx', 'sxdg', 't', 'tdg', 'swap', 'cx',
'cy', 'cz', 'cp', 'cu1', 'rxx', 'ryy', 'rzz', 'rzx', 'ccx',
'unitary', 'diagonal', 'delay', 'pauli'
'unitary', 'diagonal', 'delay', 'pauli', 'ecr'
])
if method == 'matrix_product_state':
return sorted([
Expand Down
2 changes: 1 addition & 1 deletion qiskit_aer/noise/noise_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class NoiseModel:
'y', 'z', 'h', 's', 'sdg', 'sx', 'sxdg', 't', 'tdg'])
_2qubit_instructions = set([
'swap', 'cx', 'cy', 'cz', 'csx', 'cp', 'cu', 'cu1', 'cu2', 'cu3', 'rxx',
'ryy', 'rzz', 'rzx'])
'ryy', 'rzz', 'rzx', 'ecr'])
_3qubit_instructions = set(['ccx', 'cswap'])

def __init__(self, basis_gates=None):
Expand Down
11 changes: 9 additions & 2 deletions src/framework/linalg/matrix_utils/matrix_defs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class Matrix {
const static cmatrix_t CY; // name: "cy"
const static cmatrix_t CZ; // name: "cz"
const static cmatrix_t SWAP; // name: "swap"
const static cmatrix_t ECR; // name: "ecr"

// Identity Matrix
static cmatrix_t identity(size_t dim);
Expand Down Expand Up @@ -195,14 +196,20 @@ const cmatrix_t Matrix::SWAP =
{{0, 0}, {1, 0}, {0, 0}, {0, 0}},
{{0, 0}, {0, 0}, {0, 0}, {1, 0}}});

const cmatrix_t Matrix::ECR =
Utils::make_matrix<complex_t>({{{0, 0}, {1. / std::sqrt(2.), 0}, {0, 0}, {0, 1. / std::sqrt(2.)}},
{{1. / std::sqrt(2.), 0}, {0, 0}, {0, -1. / std::sqrt(2.)}, {0, 0}},
{{0, 0}, {0, 1. / std::sqrt(2.)}, {0, 0}, {1. / std::sqrt(2.), 0}},
{{0, -1. / std::sqrt(2.)}, {0, 0}, {1. / std::sqrt(2.), 0}, {0, 0}}});

// Lookup table
const stringmap_t<const cmatrix_t *> Matrix::label_map_ = {
{"id", &Matrix::I}, {"x", &Matrix::X}, {"y", &Matrix::Y},
{"z", &Matrix::Z}, {"h", &Matrix::H}, {"s", &Matrix::S},
{"sdg", &Matrix::SDG}, {"t", &Matrix::T}, {"tdg", &Matrix::TDG},
{"x90", &Matrix::X90}, {"cx", &Matrix::CX}, {"cy", &Matrix::CY},
{"cz", &Matrix::CZ}, {"swap", &Matrix::SWAP}, {"sx", &Matrix::SX},
{"sxdg", &Matrix::SXDG}, {"delay", &Matrix::I}};
{"sxdg", &Matrix::SXDG}, {"delay", &Matrix::I}, {"ecr", &Matrix::ECR}};

cmatrix_t Matrix::identity(size_t dim) {
cmatrix_t mat(dim, dim);
Expand Down Expand Up @@ -392,4 +399,4 @@ cmatrix_t Matrix::cphase_diag(double theta) {
//------------------------------------------------------------------------------
} // end namespace AER
//------------------------------------------------------------------------------
#endif
#endif
9 changes: 7 additions & 2 deletions src/framework/linalg/matrix_utils/smatrix_defs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class SMatrix {
const static cmatrix_t CY; // name: "cy"
const static cmatrix_t CZ; // name: "cz"
const static cmatrix_t SWAP; // name: "swap"
const static cmatrix_t ECR; // name: "ecr"

// Identity Matrix
static cmatrix_t identity(size_t dim);
Expand Down Expand Up @@ -171,14 +172,18 @@ const cmatrix_t SMatrix::CZ = Utils::unitary_superop(Matrix::CZ);

const cmatrix_t SMatrix::SWAP = Utils::unitary_superop(Matrix::SWAP);

const cmatrix_t SMatrix::ECR = Utils::unitary_superop(Matrix::ECR);



// Lookup table
const stringmap_t<const cmatrix_t *> SMatrix::label_map_ = {
{"id", &SMatrix::I}, {"x", &SMatrix::X}, {"y", &SMatrix::Y},
{"z", &SMatrix::Z}, {"h", &SMatrix::H}, {"s", &SMatrix::S},
{"sdg", &SMatrix::SDG}, {"t", &SMatrix::T}, {"tdg", &SMatrix::TDG},
{"x90", &SMatrix::X90}, {"cx", &SMatrix::CX}, {"cy", &SMatrix::CY},
{"cz", &SMatrix::CZ}, {"swap", &SMatrix::SWAP}, {"sx", &SMatrix::SX},
{"sxdg", &SMatrix::SXDG}, {"delay", &SMatrix::I}};
{"sxdg", &SMatrix::SXDG}, {"delay", &SMatrix::I}, {"ecr", &SMatrix::ECR}};

cmatrix_t SMatrix::identity(size_t dim) { return Matrix::identity(dim * dim); }

Expand Down Expand Up @@ -315,4 +320,4 @@ cmatrix_t SMatrix::reset(size_t dim) {
//------------------------------------------------------------------------------
} // end namespace AER
//------------------------------------------------------------------------------
#endif
#endif
8 changes: 6 additions & 2 deletions src/framework/linalg/matrix_utils/vmatrix_defs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class VMatrix {
const static cvector_t CY; // name: "cy"
const static cvector_t CZ; // name: "cz"
const static cvector_t SWAP; // name: "swap"
const static cvector_t ECR; // name: "ECR"

// Identity Matrix
static cvector_t identity(size_t dim);
Expand Down Expand Up @@ -170,14 +171,17 @@ const cvector_t VMatrix::CZ = Utils::vectorize_matrix(Matrix::CZ);

const cvector_t VMatrix::SWAP = Utils::vectorize_matrix(Matrix::SWAP);

const cvector_t VMatrix::ECR = Utils::vectorize_matrix(Matrix::ECR);


// Lookup table
const stringmap_t<const cvector_t *> VMatrix::label_map_ = {
{"id", &VMatrix::I}, {"x", &VMatrix::X}, {"y", &VMatrix::Y},
{"z", &VMatrix::Z}, {"h", &VMatrix::H}, {"s", &VMatrix::S},
{"sdg", &VMatrix::SDG}, {"t", &VMatrix::T}, {"tdg", &VMatrix::TDG},
{"x90", &VMatrix::X90}, {"cx", &VMatrix::CX}, {"cy", &VMatrix::CY},
{"cz", &VMatrix::CZ}, {"swap", &VMatrix::SWAP}, {"sx", &VMatrix::SX},
{"sxdg", &VMatrix::SXDG}, {"delay", &VMatrix::I}};
{"sxdg", &VMatrix::SXDG}, {"delay", &VMatrix::I}, {"ecr", &VMatrix::ECR}};

cvector_t VMatrix::identity(size_t dim) {
cvector_t mat(dim * dim);
Expand Down Expand Up @@ -372,4 +376,4 @@ cvector_t VMatrix::cphase_diag(double theta) {
//------------------------------------------------------------------------------
} // end namespace AER
//------------------------------------------------------------------------------
#endif
#endif
3 changes: 3 additions & 0 deletions src/simulators/density_matrix/densitymatrix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ class DensityMatrix : public UnitaryMatrix<data_t> {
// Apply a 2-qubit SWAP gate to the state vector
void apply_swap(const uint_t q0, const uint_t q1);

// Apply a 2-qubit SWAP gate to the state vector
void apply_ecr(const uint_t q0, const uint_t q1);

// Apply a single-qubit Pauli-X gate to the state vector
void apply_x(const uint_t qubit);

Expand Down
9 changes: 7 additions & 2 deletions src/simulators/density_matrix/densitymatrix_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ const Operations::OpSet StateOpSet(
{"U", "CX", "u1", "u2", "u3", "u", "cx", "cy", "cz",
"swap", "id", "x", "y", "z", "h", "s", "sdg", "t",
"tdg", "ccx", "r", "rx", "ry", "rz", "rxx", "ryy", "rzz",
"rzx", "p", "cp", "cu1", "sx", "sxdg", "x90", "delay", "pauli"});
"rzx", "p", "cp", "cu1", "sx", "sxdg", "x90", "delay", "pauli",
"ecr"});

// Allowed gates enum class
enum class Gates {
u1, u2, u3, r, rx,ry, rz, id, x, y, z, h, s, sdg, sx, sxdg, t, tdg,
cx, cy, cz, swap, rxx, ryy, rzz, rzx, ccx, cp, pauli
cx, cy, cz, swap, rxx, ryy, rzz, rzx, ccx, cp, pauli, ecr
};

//=========================================================================
Expand Down Expand Up @@ -301,6 +302,7 @@ const stringmap_t<Gates> State<densmat_t>::gateset_({
{"ryy", Gates::ryy}, // Pauli-YY rotation gate
{"rzz", Gates::rzz}, // Pauli-ZZ rotation gate
{"rzx", Gates::rzx}, // Pauli-ZX rotation gate
{"ecr", Gates::ecr}, // ECR Gate
// Three-qubit gates
{"ccx", Gates::ccx}, // Controlled-CX gate (Toffoli)
// Pauli gate
Expand Down Expand Up @@ -1042,6 +1044,9 @@ void State<densmat_t>::apply_gate(const int_t iChunk, const Operations::Op &op)
case Gates::swap: {
BaseState::qregs_[iChunk].apply_swap(op.qubits[0], op.qubits[1]);
} break;
case Gates::ecr: {
BaseState::qregs_[iChunk].apply_unitary_matrix(op.qubits, Linalg::VMatrix::ECR);
} break;
case Gates::ccx:
BaseState::qregs_[iChunk].apply_toffoli(op.qubits[0], op.qubits[1], op.qubits[2]);
break;
Expand Down
8 changes: 6 additions & 2 deletions src/simulators/statevector/statevector_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,15 @@ const Operations::OpSet StateOpSet(
"r", "rx", "ry", "rz", "rxx", "ryy", "rzz", "rzx",
"ccx", "cswap", "mcx", "mcy", "mcz", "mcu1", "mcu2", "mcu3",
"mcswap", "mcphase", "mcr", "mcrx", "mcry", "mcry", "sx", "sxdg",
"csx", "mcsx", "csxdg", "mcsxdg", "delay", "pauli", "mcx_gray", "cu", "mcu", "mcp"});
"csx", "mcsx", "csxdg", "mcsxdg", "delay", "pauli", "mcx_gray", "cu", "mcu", "mcp",
"ecr"});

// Allowed gates enum class
enum class Gates {
id, h, s, sdg, t, tdg,
rxx, ryy, rzz, rzx,
mcx, mcy, mcz, mcr, mcrx, mcry,
mcrz, mcp, mcu2, mcu3, mcu, mcswap, mcsx, mcsxdg, pauli
mcrz, mcp, mcu2, mcu3, mcu, mcswap, mcsx, mcsxdg, pauli, ecr
};

//=========================================================================
Expand Down Expand Up @@ -338,6 +339,7 @@ const stringmap_t<Gates> State<statevec_t>::gateset_({
{"rzx", Gates::rzx}, // Pauli-ZX rotation gate
{"csx", Gates::mcsx}, // Controlled-Sqrt(X) gate
{"csxdg", Gates::mcsxdg}, // Controlled-Sqrt(X)dg gate
{"ecr", Gates::ecr}, // ECR Gate
// 3-qubit gates
{"ccx", Gates::mcx}, // Controlled-CX gate (Toffoli)
{"cswap", Gates::mcswap}, // Controlled SWAP gate (Fredkin)
Expand Down Expand Up @@ -1187,6 +1189,8 @@ void State<statevec_t>::apply_gate(const int_t iChunk, const Operations::Op &op)
case Gates::rzx:
BaseState::qregs_[iChunk].apply_rotation(op.qubits, QV::Rotation::zx, std::real(op.params[0]));
break;
case Gates::ecr:
BaseState::qregs_[iChunk].apply_matrix(op.qubits, Linalg::VMatrix::ECR);
case Gates::id:
break;
case Gates::h:
Expand Down
9 changes: 7 additions & 2 deletions src/simulators/superoperator/superoperator_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ const Operations::OpSet StateOpSet(
{"U", "CX", "u1", "u2", "u3", "u", "cx", "cy", "cz",
"swap", "id", "x", "y", "z", "h", "s", "sdg", "t",
"tdg", "ccx", "r", "rx", "ry", "rz", "rxx", "ryy", "rzz",
"rzx", "p", "cp", "cu1", "sx", "sxdg", "x90", "delay", "pauli"});
"rzx", "p", "cp", "cu1", "sx", "sxdg", "x90", "delay", "pauli",
"ecr"});

// Allowed gates enum class
enum class Gates {
u2, u1, u3, id, x, y, z, h, s, sdg, sx, sxdg, t, tdg, r, rx, ry, rz,
cx, cy, cz, cp, swap, rxx, ryy, rzz, rzx, ccx, pauli
cx, cy, cz, cp, swap, rxx, ryy, rzz, rzx, ccx, pauli, ecr
};

//=========================================================================
Expand Down Expand Up @@ -217,6 +218,7 @@ const stringmap_t<Gates> State<data_t>::gateset_({
{"ryy", Gates::ryy}, // Pauli-YY rotation gate
{"rzz", Gates::rzz}, // Pauli-ZZ rotation gate
{"rzx", Gates::rzx}, // Pauli-ZX rotation gate
{"ecr", Gates::ecr}, // ECR Gate
// Three-qubit gates
{"ccx", Gates::ccx}, // Controlled-CX gate (Toffoli)
{"pauli", Gates::pauli} // Multiple pauli operations at once
Expand Down Expand Up @@ -388,6 +390,9 @@ void State<data_t>::apply_gate(const Operations::Op &op) {
case Gates::rzx:
apply_matrix(op.qubits, Linalg::VMatrix::rzx(op.params[0]));
break;
case Gates::ecr:
apply_matrix(op.qubits, Linalg::VMatrix::ECR);
break;
case Gates::cx:
BaseState::qreg_.apply_cnot(op.qubits[0], op.qubits[1]);
break;
Expand Down
7 changes: 6 additions & 1 deletion src/simulators/unitary/unitary_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,14 @@ const Operations::OpSet StateOpSet(
"r", "rx", "ry", "rz", "rxx", "ryy", "rzz", "rzx",
"ccx", "cswap", "mcx", "mcy", "mcz", "mcu1", "mcu2", "mcu3",
"mcswap", "mcphase", "mcr", "mcrx", "mcry", "mcry", "sx", "sxdg", "csx",
"mcsx", "csxdg", "mcsxdg", "delay", "pauli", "cu", "mcu", "mcp"});
"mcsx", "csxdg", "mcsxdg", "delay", "pauli", "cu", "mcu", "mcp", "ecr"});

// Allowed gates enum class
enum class Gates {
id, h, s, sdg, t, tdg, rxx, ryy, rzz, rzx,
mcx, mcy, mcz, mcr, mcrx, mcry, mcrz, mcp,
mcu2, mcu3, mcu, mcswap, mcsx, mcsxdg, pauli,
ecr
};

//=========================================================================
Expand Down Expand Up @@ -244,6 +245,7 @@ const stringmap_t<Gates> State<unitary_matrix_t>::gateset_({
{"rzx", Gates::rzx}, // Pauli-ZX rotation gate
{"csx", Gates::mcsx}, // Controlled-Sqrt(X) gate
{"csxdg", Gates::mcsxdg},// Controlled-Sqrt(X)dg gate
{"ecr", Gates::ecr}, // ECR Gate
// Three-qubit gates
{"ccx", Gates::mcx}, // Controlled-CX gate (Toffoli)
{"cswap", Gates::mcswap}, // Controlled-SWAP gate (Fredkin)
Expand Down Expand Up @@ -583,6 +585,9 @@ void State<unitary_matrix_t>::apply_gate(const int_t iChunk, const Operations::O
case Gates::rzx:
BaseState::qregs_[iChunk].apply_matrix(op.qubits, Linalg::VMatrix::rzx(op.params[0]));
break;
case Gates::ecr:
BaseState::qregs_[iChunk].apply_matrix(op.qubits, Linalg::VMatrix::ECR);
break;
case Gates::id:
break;
case Gates::h:
Expand Down
3 changes: 2 additions & 1 deletion test/terra/backends/aer_simulator/test_standard_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
C4XGate, CCXGate, CHGate, CSXGate, CSwapGate, CPhaseGate, CRXGate, CRYGate,
CRZGate, CUGate, CU1Gate, CU3Gate, CUGate, PhaseGate, RC3XGate, RCCXGate, RGate,
RXGate, RXXGate, RYGate, RYYGate, RZGate, RZXGate, RZZGate, UGate, U1Gate, U2Gate,
U3Gate, UGate, MCXGate, MCPhaseGate, MCXGrayCode)
U3Gate, UGate, MCXGate, MCPhaseGate, MCXGrayCode, ECRGate)


CLIFFORD_GATES = [
Expand Down Expand Up @@ -57,6 +57,7 @@
(CHGate, 0, False),
(CSXGate, 0, False),
(CSwapGate, 0, False),
(ECRGate, 0, False),
# Parameterized Gates
(CPhaseGate, 1, False),
(CRXGate, 1, False),
Expand Down

0 comments on commit ca8bd21

Please sign in to comment.