Skip to content

Commit

Permalink
Merge pull request #155 from qulacs/add-control-patch
Browse files Browse the repository at this point in the history
Add control patch
  • Loading branch information
gandalfr-KY authored Aug 20, 2024
2 parents 7f52c4b + f321735 commit f2ca7e1
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 73 deletions.
1 change: 0 additions & 1 deletion scaluq/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ target_sources(scaluq PRIVATE
gate/update_ops_dense_matrix.cpp
gate/update_ops_standard.cpp
gate/update_ops_pauli.cpp
gate/update_ops_quantum_matrix.cpp
# gate/merge_gate.cpp
operator/pauli_operator.cpp
operator/operator.cpp
Expand Down
6 changes: 6 additions & 0 deletions scaluq/gate/update_ops.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ void two_target_dense_matrix_gate(UINT target_mask,
const matrix_4_4& matrix,
StateVector& state);

void one_target_diagonal_matrix_gate(UINT target_mask,
UINT control_mask,
const diagonal_matrix_2_2& diag,
StateVector& state);

void u1_gate(UINT target_mask, UINT control_mask, double lambda, StateVector& state);

void u2_gate(UINT target_mask, UINT control_mask, double phi, double lambda, StateVector& state);
Expand All @@ -76,5 +81,6 @@ void pauli_rotation_gate(UINT control_mask,
const PauliOperator& pauli,
double angle,
StateVector& state);

} // namespace internal
} // namespace scaluq
1 change: 1 addition & 0 deletions scaluq/gate/update_ops_dense_matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "../types.hpp"
#include "../util/utility.hpp"
#include "update_ops.hpp"

namespace scaluq {
namespace internal {
Expand Down
45 changes: 0 additions & 45 deletions scaluq/gate/update_ops_quantum_matrix.cpp

This file was deleted.

54 changes: 42 additions & 12 deletions scaluq/gate/update_ops_standard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,7 @@ void z_gate(UINT target_mask, UINT control_mask, StateVector& state) {
}

void h_gate(UINT target_mask, UINT control_mask, StateVector& state) {
Kokkos::parallel_for(
state.dim() >> std::popcount(target_mask | control_mask), KOKKOS_LAMBDA(UINT it) {
UINT i = insert_zero_at_mask_positions(it, control_mask | target_mask) | control_mask;
Complex a = state._raw[i];
Complex b = state._raw[i | target_mask];
state._raw[i] = (a + b) * INVERSE_SQRT2();
state._raw[i | target_mask] = (a - b) * INVERSE_SQRT2();
});
Kokkos::fence();
one_target_dense_matrix_gate(target_mask, control_mask, HADAMARD_MATRIX(), state);
}

void one_target_phase_gate(UINT target_mask, UINT control_mask, Complex phase, StateVector& state) {
Expand Down Expand Up @@ -126,11 +118,15 @@ void ry_gate(UINT target_mask, UINT control_mask, double angle, StateVector& sta

void one_target_diagonal_matrix_gate(UINT target_mask,
UINT control_mask,
const diagonal_matrix_2_2 diag,
const diagonal_matrix_2_2& diag,
StateVector& state) {
Kokkos::parallel_for(
state.dim(),
KOKKOS_LAMBDA(UINT it) { state._raw[it] *= diag.val[bool(it & target_mask)]; });
state.dim() >> std::popcount(target_mask | control_mask), KOKKOS_LAMBDA(UINT it) {
UINT basis =
insert_zero_at_mask_positions(it, target_mask | control_mask) | control_mask;
state._raw[basis] *= diag.val[0];
state._raw[basis | target_mask] *= diag.val[1];
});
Kokkos::fence();
}

Expand All @@ -141,6 +137,40 @@ void rz_gate(UINT target_mask, UINT control_mask, double angle, StateVector& sta
one_target_diagonal_matrix_gate(target_mask, control_mask, diag, state);
}

matrix_2_2 get_IBMQ_matrix(double theta, double phi, double lambda) {
Complex exp_val1 = Kokkos::exp(Complex(0, phi));
Complex exp_val2 = Kokkos::exp(Complex(0, lambda));
Complex cos_val = Kokkos::cos(theta / 2.);
Complex sin_val = Kokkos::sin(theta / 2.);
return {cos_val, -exp_val2 * sin_val, exp_val1 * sin_val, exp_val1 * exp_val2 * cos_val};
}

void u1_gate(UINT target_mask, UINT control_mask, double lambda, StateVector& state) {
Complex exp_val = Kokkos::exp(Complex(0, lambda));
Kokkos::parallel_for(
state.dim() >> (std::popcount(target_mask | control_mask)), KOKKOS_LAMBDA(UINT it) {
UINT i = internal::insert_zero_at_mask_positions(it, target_mask | control_mask) |
control_mask;
state._raw[i | target_mask] *= exp_val;
});
Kokkos::fence();
}

void u2_gate(UINT target_mask, UINT control_mask, double phi, double lambda, StateVector& state) {
one_target_dense_matrix_gate(
target_mask, control_mask, get_IBMQ_matrix(PI() / 2., phi, lambda), state);
}

void u3_gate(UINT target_mask,
UINT control_mask,
double theta,
double phi,
double lambda,
StateVector& state) {
one_target_dense_matrix_gate(
target_mask, control_mask, get_IBMQ_matrix(theta, phi, lambda), state);
}

void swap_gate(UINT target_mask, UINT control_mask, StateVector& state) {
// '- target' is used for bit manipulation on unsigned type, not for its numerical meaning.
UINT lower_target_mask = target_mask & -target_mask;
Expand Down
15 changes: 0 additions & 15 deletions scaluq/util/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,6 @@ KOKKOS_INLINE_FUNCTION UINT insert_zero_to_basis_index(UINT basis_index, UINT in
return temp_basis | (basis_index & mask);
}

/**
* Inserts two 0 bits at specified indexes in basis_index.
* Example: insert_zero_to_basis_index(0b11001, 1, 5) -> 0b1010001.
* ^ ^
*/
KOKKOS_INLINE_FUNCTION UINT insert_zero_to_basis_index(UINT basis_index,
UINT insert_index1,
UINT insert_index2) {
auto [lidx, uidx] = Kokkos::minmax(insert_index1, insert_index2);
UINT lmask = (1ULL << lidx) - 1;
UINT umask = (1ULL << uidx) - 1;
basis_index = ((basis_index >> lidx) << (lidx + 1)) | (basis_index & lmask);
return ((basis_index >> uidx) << (uidx + 1)) | (basis_index & umask);
}

/**
* Inserts multiple 0 bits at specified positions in basis_index.
* Example: insert_zero_to_basis_index(0b11111, 0x100101) -> 0b11011010.
Expand Down

0 comments on commit f2ca7e1

Please sign in to comment.