Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions qiskit/providers/aer/backends/qasm_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ class QasmSimulator(AerBackend):
'coupling_map': None,
'basis_gates': [
'u1', 'u2', 'u3', 'cx', 'cz', 'id', 'x', 'y', 'z', 'h', 's', 'sdg',
't', 'tdg', 'swap', 'ccx', 'unitary', 'initialize', 'cu1', 'cu2',
'cu3', 'cswap', 'mcx', 'mcy', 'mcz', 'mcu1', 'mcu2', 'mcu3',
'mcswap', 'multiplexer', 'kraus', 'roerror'
't', 'tdg', 'swap', 'ccx', 'unitary', 'diagonal', 'initialize',
'cu1', 'cu2', 'cu3', 'cswap', 'mcx', 'mcy', 'mcz',
'mcu1', 'mcu2', 'mcu3', 'mcswap', 'multiplexer', 'kraus', 'roerror'
],
'gates': [{
'name': 'u1',
Expand Down Expand Up @@ -349,9 +349,16 @@ class QasmSimulator(AerBackend):
'name': 'unitary',
'parameters': ['matrix'],
'conditional': True,
'description': 'N-qubit arbitrary unitary gate. '
'description': 'N-qubit unitary gate. '
'The parameter is the N-qubit matrix to apply.',
'qasm_def': 'unitary(matrix) q1, q2,...'
}, {
'name': 'diagonal',
'parameters': ['diag_elements'],
'conditional': True,
'description': 'N-qubit diagonal unitary gate. The parameters are the'
' diagonal entries of the N-qubit matrix to apply.',
'qasm_def': 'TODO'
}, {
'name': 'initialize',
'parameters': ['vector'],
Expand Down
13 changes: 10 additions & 3 deletions qiskit/providers/aer/backends/statevector_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ class StatevectorSimulator(AerBackend):
'coupling_map': None,
'basis_gates': [
'u1', 'u2', 'u3', 'cx', 'cz', 'id', 'x', 'y', 'z', 'h', 's', 'sdg',
't', 'tdg', 'swap', 'ccx', 'unitary', 'initialize', 'cu1', 'cu2',
'cu3', 'cswap', 'mcx', 'mcy', 'mcz', 'mcu1', 'mcu2', 'mcu3',
'mcswap', 'multiplexer',
't', 'tdg', 'swap', 'ccx', 'unitary', 'diagonal', 'initialize',
'cu1', 'cu2', 'cu3', 'cswap', 'mcx', 'mcy', 'mcz',
'mcu1', 'mcu2', 'mcu3', 'mcswap', 'multiplexer',
],
'gates': [{
'name': 'u1',
Expand Down Expand Up @@ -207,6 +207,13 @@ class StatevectorSimulator(AerBackend):
'description': 'N-qubit arbitrary unitary gate. '
'The parameter is the N-qubit matrix to apply.',
'qasm_def': 'unitary(matrix) q1, q2,...'
}, {
'name': 'diagonal',
'parameters': ['diag_elements'],
'conditional': True,
'description': 'N-qubit diagonal unitary gate. The parameters are the'
' diagonal entries of the N-qubit matrix to apply.',
'qasm_def': 'TODO'
}, {
'name': 'initialize',
'parameters': ['vector'],
Expand Down
9 changes: 8 additions & 1 deletion qiskit/providers/aer/backends/unitary_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class UnitarySimulator(AerBackend):
'coupling_map': None,
'basis_gates': [
'u1', 'u2', 'u3', 'cx', 'cz', 'id', 'x', 'y', 'z', 'h', 's', 'sdg',
't', 'tdg', 'swap', 'ccx', 'unitary', 'cu1', 'cu2',
't', 'tdg', 'swap', 'ccx', 'unitary', 'diagonal', 'cu1', 'cu2',
'cu3', 'cswap', 'mcx', 'mcy', 'mcz', 'mcu1', 'mcu2', 'mcu3',
'mcswap', 'multiplexer',
],
Expand Down Expand Up @@ -214,6 +214,13 @@ class UnitarySimulator(AerBackend):
'description': 'N-qubit arbitrary unitary gate. '
'The parameter is the N-qubit matrix to apply.',
'qasm_def': 'unitary(matrix) q1, q2,...'
}, {
'name': 'diagonal',
'parameters': ['diag_elements'],
'conditional': True,
'description': 'N-qubit diagonal unitary gate. The parameters are the'
' diagonal entries of the N-qubit matrix to apply.',
'qasm_def': 'TODO'
}, {
'name': 'cu1',
'parameters': ['lam'],
Expand Down
40 changes: 38 additions & 2 deletions src/framework/operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "framework/types.hpp"
#include "framework/json.hpp"
#include "framework/utils.hpp"
#include "framework/linalg/almost_equal.hpp"

namespace AER {
namespace Operations {
Expand All @@ -36,7 +37,7 @@ enum class RegComparison {Equal, NotEqual, Less, LessEqual, Greater, GreaterEqua
// Enum class for operation types
enum class OpType {
gate, measure, reset, bfunc, barrier, snapshot,
matrix, multiplexer, kraus, superop, roerror, noise_switch, initialize
matrix, diagonal_matrix, multiplexer, kraus, superop, roerror, noise_switch, initialize
};

inline std::ostream& operator<<(std::ostream& stream, const OpType& type) {
Expand All @@ -60,7 +61,10 @@ inline std::ostream& operator<<(std::ostream& stream, const OpType& type) {
stream << "snapshot";
break;
case OpType::matrix:
stream << "matrix";
stream << "unitary";
break;
case OpType::diagonal_matrix:
stream << "diagonal";
break;
case OpType::multiplexer:
stream << "multiplexer";
Expand Down Expand Up @@ -561,6 +565,7 @@ Op json_to_op_snapshot_pauli(const json_t &js);

// Matrices
Op json_to_op_unitary(const json_t &js);
Op json_to_op_diagonal(const json_t &js);
Op json_to_op_superop(const json_t &js);
Op json_to_op_multiplexer(const json_t &js);
Op json_to_op_kraus(const json_t &js);
Expand Down Expand Up @@ -596,6 +601,8 @@ Op json_to_op(const json_t &js) {
// Arbitrary matrix gates
if (name == "unitary")
return json_to_op_unitary(js);
if (name == "diagonal")
return json_to_op_diagonal(js);
if (name == "superop")
return json_to_op_superop(js);
// Snapshot
Expand Down Expand Up @@ -866,6 +873,35 @@ Op json_to_op_unitary(const json_t &js) {
return op;
}

Op json_to_op_diagonal(const json_t &js) {
Op op;
op.type = OpType::diagonal_matrix;
op.name = "diagonal";
JSON::get_value(op.qubits, "qubits", js);
JSON::get_value(op.params, "params", js);

// Validation
check_empty_qubits(op);
check_duplicate_qubits(op);
if (op.params.size() != 1ULL << op.qubits.size()) {
throw std::invalid_argument("\"diagonal\" matrix is wrong size.");
}
for (const auto val : op.params) {
if (!Linalg::almost_equal(std::abs(val), 1.0)) {
throw std::invalid_argument("\"diagonal\" matrix is not unitary.");
}
}

// Check for a label
std::string label;
JSON::get_value(label, "label", js);
op.string_params.push_back(label);

// Conditional
add_condtional(Allowed::Yes, op, js);
return op;
}

Op json_to_op_superop(const json_t &js) {
// Warning: we don't check superoperator is valid!
Op op;
Expand Down
4 changes: 4 additions & 0 deletions src/simulators/density_matrix/densitymatrix_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class State : public Base::State<densmat_t> {
Operations::OpType::bfunc,
Operations::OpType::roerror,
Operations::OpType::matrix,
Operations::OpType::diagonal_matrix,
Operations::OpType::kraus,
Operations::OpType::superop
});
Expand Down Expand Up @@ -417,6 +418,9 @@ void State<densmat_t>::apply_ops(const std::vector<Operations::Op> &ops,
case Operations::OpType::matrix:
apply_matrix(op.qubits, op.mats[0]);
break;
case Operations::OpType::diagonal_matrix:
BaseState::qreg_.apply_diagonal_matrix(op.qubits, op.params);
break;
case Operations::OpType::superop:
BaseState::qreg_.apply_superop_matrix(op.qubits, Utils::vectorize_matrix(op.mats[0]));
break;
Expand Down
4 changes: 4 additions & 0 deletions src/simulators/statevector/statevector_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class State : public Base::State<statevec_t> {
Operations::OpType::bfunc,
Operations::OpType::roerror,
Operations::OpType::matrix,
Operations::OpType::diagonal_matrix,
Operations::OpType::multiplexer,
Operations::OpType::kraus
});
Expand Down Expand Up @@ -469,6 +470,9 @@ void State<statevec_t>::apply_ops(const std::vector<Operations::Op> &ops,
case Operations::OpType::matrix:
apply_matrix(op);
break;
case Operations::OpType::diagonal_matrix:
BaseState::qreg_.apply_diagonal_matrix(op.qubits, op.params);
break;
case Operations::OpType::multiplexer:
apply_multiplexer(op.regs[0], op.regs[1], op.mats); // control qubits ([0]) & target qubits([1])
break;
Expand Down
4 changes: 4 additions & 0 deletions src/simulators/superoperator/superoperator_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class State : public Base::State<data_t> {
Operations::OpType::snapshot,
Operations::OpType::barrier,
Operations::OpType::matrix,
Operations::OpType::diagonal_matrix,
Operations::OpType::kraus,
Operations::OpType::superop
});
Expand Down Expand Up @@ -234,6 +235,9 @@ void State<data_t>::apply_ops(const std::vector<Operations::Op> &ops,
case Operations::OpType::matrix:
apply_matrix(op.qubits, op.mats[0]);
break;
case Operations::OpType::diagonal_matrix:
BaseState::qreg_.apply_diagonal_matrix(op.qubits, op.params);
break;
case Operations::OpType::kraus:
apply_kraus(op.qubits, op.mats);
break;
Expand Down
13 changes: 10 additions & 3 deletions src/simulators/unitary/unitary_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,13 @@ class State : public Base::State<unitary_matrix_t> {

// Return the set of qobj instruction types supported by the State
virtual Operations::OpSet::optypeset_t allowed_ops() const override {
return Operations::OpSet::optypeset_t(
{Operations::OpType::gate, Operations::OpType::barrier,
Operations::OpType::matrix, Operations::OpType::snapshot});
return Operations::OpSet::optypeset_t({
Operations::OpType::gate,
Operations::OpType::barrier,
Operations::OpType::matrix,
Operations::OpType::diagonal_matrix,
Operations::OpType::snapshot
});
}

// Return the set of qobj gate instruction names supported by the State
Expand Down Expand Up @@ -233,6 +237,9 @@ void State<unitary_matrix_t>::apply_ops(
case Operations::OpType::matrix:
apply_matrix(op.qubits, op.mats[0]);
break;
case Operations::OpType::diagonal_matrix:
BaseState::qreg_.apply_diagonal_matrix(op.qubits, op.params);
break;
default:
throw std::invalid_argument(
"QubitUnitary::State::invalid instruction \'" + op.name + "\'.");
Expand Down
27 changes: 25 additions & 2 deletions test/terra/backends/qasm_simulator/qasm_unitary_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
QasmSimulator Integration Tests
"""


from test.terra.reference import ref_unitary_gate, ref_diagonal_gate

from qiskit import execute
from qiskit.providers.aer import QasmSimulator

from test.terra.reference import ref_unitary_gate


class QasmUnitaryGateTests:
"""QasmSimulator additional tests."""
Expand Down Expand Up @@ -48,3 +49,25 @@ def test_random_unitary_gate(self):
result = execute(circuits, self.SIMULATOR, shots=shots).result()
self.assertTrue(getattr(result, 'success', False))
self.compare_counts(result, circuits, targets, delta=0.05 * shots)


class QasmDiagonalGateTests:
"""QasmSimulator additional tests."""

SIMULATOR = QasmSimulator()
BACKEND_OPTS = {}

# ---------------------------------------------------------------------
# Test unitary gate qobj instruction
# ---------------------------------------------------------------------

def test_diagonal_gate(self):
"""Test simulation with unitary gate circuit instructions."""
shots = 100
circuits = ref_diagonal_gate.diagonal_gate_circuits_deterministic(
final_measure=True)
targets = ref_diagonal_gate.diagonal_gate_counts_deterministic(
shots)
result = execute(circuits, self.SIMULATOR, shots=shots).result()
self.assertTrue(getattr(result, 'success', False))
self.compare_counts(result, circuits, targets, delta=0)
14 changes: 14 additions & 0 deletions test/terra/backends/statevector_simulator/statevector_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from test.terra.reference import ref_2q_clifford
from test.terra.reference import ref_non_clifford
from test.terra.reference import ref_unitary_gate
from test.terra.reference import ref_diagonal_gate

from qiskit import execute
from qiskit.compiler import assemble
Expand Down Expand Up @@ -1072,6 +1073,19 @@ def test_unitary_gate(self):
self.assertTrue(getattr(result, 'success', False))
self.compare_statevector(result, circuits, targets)

def test_diagonal_gate(self):
"""Test simulation with diagonal gate circuit instructions."""
circuits = ref_diagonal_gate.diagonal_gate_circuits_deterministic(
final_measure=False)
targets = ref_diagonal_gate.diagonal_gate_statevector_deterministic()
job = execute(circuits,
self.SIMULATOR,
shots=1,
backend_options=self.BACKEND_OPTS)
result = job.result()
self.assertTrue(getattr(result, 'success', False))
self.compare_statevector(result, circuits, targets)

# ---------------------------------------------------------------------
# Test cu1 gate
# ---------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions test/terra/backends/test_qasm_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from test.terra.backends.qasm_simulator.qasm_noncliffords import QasmNonCliffordTestsWaltzBasis
from test.terra.backends.qasm_simulator.qasm_noncliffords import QasmNonCliffordTestsMinimalBasis
from test.terra.backends.qasm_simulator.qasm_unitary_gate import QasmUnitaryGateTests
from test.terra.backends.qasm_simulator.qasm_unitary_gate import QasmDiagonalGateTests
from test.terra.backends.qasm_simulator.qasm_initialize import QasmInitializeTests
# Conditional instruction tests
from test.terra.backends.qasm_simulator.qasm_conditional import QasmConditionalGateTests
Expand Down Expand Up @@ -77,6 +78,7 @@ class TestQasmSimulator(common.QiskitAerTestCase,
QasmAlgorithmTestsWaltzBasis,
QasmAlgorithmTestsMinimalBasis,
QasmUnitaryGateTests,
QasmDiagonalGateTests,
QasmReadoutNoiseTests,
QasmPauliNoiseTests,
QasmThreadManagementTests,
Expand Down
3 changes: 2 additions & 1 deletion test/terra/backends/test_qasm_simulator_density_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from test.terra.backends.qasm_simulator.qasm_noncliffords import QasmNonCliffordTestsWaltzBasis
from test.terra.backends.qasm_simulator.qasm_noncliffords import QasmNonCliffordTestsMinimalBasis
from test.terra.backends.qasm_simulator.qasm_unitary_gate import QasmUnitaryGateTests
from test.terra.backends.qasm_simulator.qasm_unitary_gate import QasmDiagonalGateTests
# Conditional instruction tests
from test.terra.backends.qasm_simulator.qasm_conditional import QasmConditionalGateTests
from test.terra.backends.qasm_simulator.qasm_conditional import QasmConditionalUnitaryTests
Expand Down Expand Up @@ -61,7 +62,7 @@ class DensityMatrixTests(
QasmCliffordTestsMinimalBasis, QasmNonCliffordTests,
QasmNonCliffordTestsWaltzBasis, QasmNonCliffordTestsMinimalBasis,
QasmAlgorithmTests, QasmAlgorithmTestsWaltzBasis,
QasmAlgorithmTestsMinimalBasis, QasmUnitaryGateTests,
QasmAlgorithmTestsMinimalBasis, QasmUnitaryGateTests, QasmDiagonalGateTests,
QasmReadoutNoiseTests, QasmPauliNoiseTests, QasmResetNoiseTests,
QasmKrausNoiseTests, QasmSnapshotStatevectorTests,
QasmSnapshotDensityMatrixTests, QasmSnapshotProbabilitiesTests,
Expand Down
3 changes: 2 additions & 1 deletion test/terra/backends/test_qasm_simulator_statevector.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from test.terra.backends.qasm_simulator.qasm_noncliffords import QasmNonCliffordTestsWaltzBasis
from test.terra.backends.qasm_simulator.qasm_noncliffords import QasmNonCliffordTestsMinimalBasis
from test.terra.backends.qasm_simulator.qasm_unitary_gate import QasmUnitaryGateTests
from test.terra.backends.qasm_simulator.qasm_unitary_gate import QasmDiagonalGateTests
from test.terra.backends.qasm_simulator.qasm_initialize import QasmInitializeTests
# Conditional instruction tests
from test.terra.backends.qasm_simulator.qasm_conditional import QasmConditionalGateTests
Expand Down Expand Up @@ -66,7 +67,7 @@ class StatevectorTests(
QasmCliffordTestsMinimalBasis, QasmNonCliffordTests,
QasmNonCliffordTestsWaltzBasis, QasmNonCliffordTestsMinimalBasis,
QasmAlgorithmTests, QasmAlgorithmTestsWaltzBasis,
QasmAlgorithmTestsMinimalBasis, QasmUnitaryGateTests,
QasmAlgorithmTestsMinimalBasis, QasmUnitaryGateTests, QasmDiagonalGateTests,
QasmReadoutNoiseTests, QasmPauliNoiseTests, QasmThreadManagementTests,
QasmFusionTests, QasmDelayMeasureTests, QasmQubitsTruncateTests,
QasmResetNoiseTests, QasmKrausNoiseTests, QasmBasicsTests,
Expand Down
14 changes: 14 additions & 0 deletions test/terra/backends/unitary_simulator/unitary_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from test.terra.reference import ref_2q_clifford
from test.terra.reference import ref_non_clifford
from test.terra.reference import ref_unitary_gate
from test.terra.reference import ref_diagonal_gate

from qiskit import execute
from qiskit.providers.aer import UnitarySimulator
Expand Down Expand Up @@ -1050,6 +1051,19 @@ def test_unitary_gate(self):
self.assertTrue(getattr(result, 'success', False))
self.compare_unitary(result, circuits, targets)

def test_diagonal_gate(self):
"""Test simulation with diagonal gate circuit instructions."""
circuits = ref_diagonal_gate.diagonal_gate_circuits_deterministic(
final_measure=False)
targets = ref_diagonal_gate.diagonal_gate_unitary_deterministic()
job = execute(circuits,
self.SIMULATOR,
shots=1,
backend_options=self.BACKEND_OPTS)
result = job.result()
self.assertTrue(getattr(result, 'success', False))
self.compare_unitary(result, circuits, targets)

# ---------------------------------------------------------------------
# Test cswap-gate (Fredkin)
# ---------------------------------------------------------------------
Expand Down
Loading