Skip to content

Commit

Permalink
Merge pull request #100 from qulacs/fix-bugs
Browse files Browse the repository at this point in the history
const UINT& -> UINT
  • Loading branch information
gandalfr-KY authored May 21, 2024
2 parents 0bc670c + f1d4efb commit bb5d1c7
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 51 deletions.
2 changes: 1 addition & 1 deletion scaluq/gate/update_ops_npair_qubit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ void fusedswap_gate(UINT target_qubit_index_0,
const UINT else_mask = (1 << n_qubits) - 1 - kblk_mask - jblk_mask;

Kokkos::parallel_for(
state.dim(), KOKKOS_LAMBDA(const UINT& i) {
state.dim(), KOKKOS_LAMBDA(UINT i) {
const UINT kblk = (i & kblk_mask) >> upper_index;
const UINT jblk = (i & jblk_mask) >> lower_index;
if (jblk > kblk) {
Expand Down
4 changes: 2 additions & 2 deletions scaluq/gate/update_ops_one_control_one_target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace scaluq {
namespace internal {
void cx_gate(UINT control_qubit_index, UINT target_qubit_index, StateVector& state) {
Kokkos::parallel_for(
state.dim() >> 2, KOKKOS_LAMBDA(const UINT& it) {
state.dim() >> 2, KOKKOS_LAMBDA(UINT it) {
UINT i =
internal::insert_zero_to_basis_index(it, target_qubit_index, control_qubit_index);
i |= 1ULL << control_qubit_index;
Expand All @@ -20,7 +20,7 @@ void cx_gate(UINT control_qubit_index, UINT target_qubit_index, StateVector& sta

void cz_gate(UINT control_qubit_index, UINT target_qubit_index, StateVector& state) {
Kokkos::parallel_for(
state.dim() >> 2, KOKKOS_LAMBDA(const UINT& it) {
state.dim() >> 2, KOKKOS_LAMBDA(UINT it) {
UINT i =
internal::insert_zero_to_basis_index(it, target_qubit_index, control_qubit_index);
i |= 1ULL << control_qubit_index;
Expand Down
15 changes: 7 additions & 8 deletions scaluq/gate/update_ops_one_qubit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ namespace scaluq {
namespace internal {
void x_gate(UINT target_qubit_index, StateVector& state) {
Kokkos::parallel_for(
state.dim() >> 1, KOKKOS_LAMBDA(const UINT& it) {
state.dim() >> 1, KOKKOS_LAMBDA(UINT it) {
UINT i = internal::insert_zero_to_basis_index(it, target_qubit_index);
Kokkos::Experimental::swap(state._raw[i], state._raw[i | (1ULL << target_qubit_index)]);
});
}

void y_gate(UINT target_qubit_index, StateVector& state) {
Kokkos::parallel_for(
state.dim() >> 1, KOKKOS_LAMBDA(const UINT& it) {
state.dim() >> 1, KOKKOS_LAMBDA(UINT it) {
UINT i = internal::insert_zero_to_basis_index(it, target_qubit_index);
state._raw[i] *= Complex(0, 1);
state._raw[i | (1ULL << target_qubit_index)] *= Complex(0, -1);
Expand All @@ -28,15 +28,15 @@ void y_gate(UINT target_qubit_index, StateVector& state) {

void z_gate(UINT target_qubit_index, StateVector& state) {
Kokkos::parallel_for(
state.dim() >> 1, KOKKOS_LAMBDA(const UINT& it) {
state.dim() >> 1, KOKKOS_LAMBDA(UINT it) {
UINT i = internal::insert_zero_to_basis_index(it, target_qubit_index);
state._raw[i | (1ULL << target_qubit_index)] *= Complex(-1, 0);
});
}

void h_gate(UINT target_qubit_index, StateVector& state) {
Kokkos::parallel_for(
state.dim() >> 1, KOKKOS_LAMBDA(const UINT& it) {
state.dim() >> 1, KOKKOS_LAMBDA(UINT it) {
UINT i = internal::insert_zero_to_basis_index(it, target_qubit_index);
Complex a = state._raw[i];
Complex b = state._raw[i | (1ULL << target_qubit_index)];
Expand All @@ -47,7 +47,7 @@ void h_gate(UINT target_qubit_index, StateVector& state) {

void single_qubit_phase_gate(UINT target_qubit_index, Complex phase, StateVector& state) {
Kokkos::parallel_for(
state.dim() >> 1, KOKKOS_LAMBDA(const UINT& it) {
state.dim() >> 1, KOKKOS_LAMBDA(UINT it) {
UINT i = internal::insert_zero_to_basis_index(it, target_qubit_index);
state._raw[i | (1ULL << target_qubit_index)] *= phase;
});
Expand Down Expand Up @@ -111,9 +111,8 @@ void single_qubit_diagonal_matrix_gate(UINT target_qubit_index,
const diagonal_matrix_2_2 diag,
StateVector& state) {
Kokkos::parallel_for(
state.dim(), KOKKOS_LAMBDA(const UINT& it) {
state._raw[it] *= diag.val[(it >> target_qubit_index) & 1];
});
state.dim(),
KOKKOS_LAMBDA(UINT it) { state._raw[it] *= diag.val[(it >> target_qubit_index) & 1]; });
}

void rz_gate(UINT target_qubit_index, double angle, StateVector& state) {
Expand Down
4 changes: 2 additions & 2 deletions scaluq/gate/update_ops_pauli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ void pauli_rotation_gate(const PauliOperator& pauli, double angle, StateVector&
const Complex cval_min = Complex(cosval, -sinval);
const Complex cval_pls = Complex(cosval, sinval);
Kokkos::parallel_for(
state.dim(), KOKKOS_LAMBDA(const UINT& state_idx) {
state.dim(), KOKKOS_LAMBDA(UINT state_idx) {
if (Kokkos::popcount(state_idx & phase_flip_mask) & 1) {
state._raw[state_idx] *= cval_min;
} else {
Expand All @@ -35,7 +35,7 @@ void pauli_rotation_gate(const PauliOperator& pauli, double angle, StateVector&
} else {
const UINT insert_idx = internal::BitVector(bit_flip_mask_vector).msb();
Kokkos::parallel_for(
state.dim() >> 1, KOKKOS_LAMBDA(const UINT& state_idx) {
state.dim() >> 1, KOKKOS_LAMBDA(UINT state_idx) {
UINT basis_0 = internal::insert_zero_to_basis_index(state_idx, insert_idx);
UINT basis_1 = basis_0 ^ bit_flip_mask;

Expand Down
2 changes: 1 addition & 1 deletion scaluq/gate/update_ops_two_qubit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace scaluq {
namespace internal {
void swap_gate(UINT target0, UINT target1, StateVector& state) {
Kokkos::parallel_for(
1ULL << (state.n_qubits() - 2), KOKKOS_LAMBDA(const UINT& it) {
1ULL << (state.n_qubits() - 2), KOKKOS_LAMBDA(UINT it) {
UINT basis = internal::insert_zero_to_basis_index(it, target0, target1);
Kokkos::Experimental::swap(state._raw[basis | (1ULL << target0)],
state._raw[basis | (1ULL << target1)]);
Expand Down
2 changes: 1 addition & 1 deletion scaluq/gate/update_ops_zero_qubit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ void i_gate(StateVector&) {}
void global_phase_gate(double phase, StateVector& state) {
Complex coef = Kokkos::polar(1., phase);
Kokkos::parallel_for(
state.dim(), KOKKOS_LAMBDA(const UINT& i) { state._raw[i] *= coef; });
state.dim(), KOKKOS_LAMBDA(UINT i) { state._raw[i] *= coef; });
}
} // namespace internal
} // namespace scaluq
12 changes: 6 additions & 6 deletions scaluq/operator/pauli_operator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ void PauliOperator::apply_to_state(StateVector& state_vector) const {
Complex coef = get_coef();
if (bit_flip_mask == 0) {
Kokkos::parallel_for(
state_vector.dim(), KOKKOS_LAMBDA(const UINT& state_idx) {
state_vector.dim(), KOKKOS_LAMBDA(UINT state_idx) {
if (Kokkos::popcount(state_idx & phase_flip_mask) & 1) {
state_vector._raw[state_idx] *= -coef;
} else {
Expand All @@ -131,7 +131,7 @@ void PauliOperator::apply_to_state(StateVector& state_vector) const {
UINT global_phase_90rot_count = std::popcount(bit_flip_mask & phase_flip_mask);
Complex global_phase = PHASE_M90ROT().val[global_phase_90rot_count % 4];
Kokkos::parallel_for(
state_vector.dim() >> 1, KOKKOS_LAMBDA(const UINT& state_idx) {
state_vector.dim() >> 1, KOKKOS_LAMBDA(UINT state_idx) {
UINT basis_0 = internal::insert_zero_to_basis_index(state_idx, pivot);
UINT basis_1 = basis_0 ^ bit_flip_mask;
Complex tmp1 = state_vector._raw[basis_0] * global_phase;
Expand All @@ -155,7 +155,7 @@ Complex PauliOperator::get_expectation_value(const StateVector& state_vector) co
double res;
Kokkos::parallel_reduce(
state_vector.dim(),
KOKKOS_LAMBDA(const UINT& state_idx, double& sum) {
KOKKOS_LAMBDA(UINT state_idx, double& sum) {
double tmp =
(Kokkos::conj(state_vector._raw[state_idx]) * state_vector._raw[state_idx])
.real();
Expand All @@ -171,7 +171,7 @@ Complex PauliOperator::get_expectation_value(const StateVector& state_vector) co
double res;
Kokkos::parallel_reduce(
state_vector.dim() >> 1,
KOKKOS_LAMBDA(const UINT& state_idx, double& sum) {
KOKKOS_LAMBDA(UINT state_idx, double& sum) {
UINT basis_0 = internal::insert_zero_to_basis_index(state_idx, pivot);
UINT basis_1 = basis_0 ^ bit_flip_mask;
double tmp = Kokkos::real(state_vector._raw[basis_0] *
Expand Down Expand Up @@ -199,7 +199,7 @@ Complex PauliOperator::get_transition_amplitude(const StateVector& state_vector_
Complex res;
Kokkos::parallel_reduce(
state_vector_bra.dim(),
KOKKOS_LAMBDA(const UINT& state_idx, Complex& sum) {
KOKKOS_LAMBDA(UINT state_idx, Complex & sum) {
Complex tmp = Kokkos::conj(state_vector_bra._raw[state_idx]) *
state_vector_ket._raw[state_idx];
if (Kokkos::popcount(state_idx & phase_flip_mask) & 1) tmp = -tmp;
Expand All @@ -214,7 +214,7 @@ Complex PauliOperator::get_transition_amplitude(const StateVector& state_vector_
Complex res;
Kokkos::parallel_reduce(
state_vector_bra.dim() >> 1,
KOKKOS_LAMBDA(const UINT& state_idx, Complex& sum) {
KOKKOS_LAMBDA(UINT state_idx, Complex & sum) {
UINT basis_0 = internal::insert_zero_to_basis_index(state_idx, pivot);
UINT basis_1 = basis_0 ^ bit_flip_mask;
Complex tmp1 = Kokkos::conj(state_vector_bra._raw[basis_1]) *
Expand Down
41 changes: 26 additions & 15 deletions scaluq/state/state_vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ StateVector::StateVector(UINT n_qubits)
set_zero_state();
}

void StateVector::set_amplitude_at_index(const UINT& index, const Complex& c) {
void StateVector::set_amplitude_at_index(UINT index, const Complex& c) {
Kokkos::View<Complex, Kokkos::HostSpace> host_view("single_value");
host_view() = c;
Kokkos::deep_copy(Kokkos::subview(_raw, index), host_view());
}

Complex StateVector::get_amplitude_at_index(const UINT& index) const {
Complex StateVector::get_amplitude_at_index(UINT index) const {
Kokkos::View<Complex, Kokkos::HostSpace> host_view("single_value");
Kokkos::deep_copy(host_view, Kokkos::subview(_raw, index));
return host_view();
Expand Down Expand Up @@ -44,7 +44,7 @@ StateVector StateVector::Haar_random_state(UINT n_qubits, UINT seed) {
Kokkos::Random_XorShift64_Pool<> rand_pool(seed);
StateVector state(n_qubits);
Kokkos::parallel_for(
state._dim, KOKKOS_LAMBDA(const UINT& i) {
state._dim, KOKKOS_LAMBDA(UINT i) {
auto rand_gen = rand_pool.get_state();
state._raw[i] = Complex(rand_gen.normal(0.0, 1.0), rand_gen.normal(0.0, 1.0));
rand_pool.free_state(rand_gen);
Expand All @@ -65,15 +65,15 @@ double StateVector::get_squared_norm() const {
double norm = 0.;
Kokkos::parallel_reduce(
this->_dim,
KOKKOS_CLASS_LAMBDA(const UINT& it, double& tmp) { tmp += squared_norm(this->_raw[it]); },
KOKKOS_CLASS_LAMBDA(UINT it, double& tmp) { tmp += squared_norm(this->_raw[it]); },
norm);
return norm;
}

void StateVector::normalize() {
const auto norm = std::sqrt(this->get_squared_norm());
Kokkos::parallel_for(
this->_dim, KOKKOS_CLASS_LAMBDA(const UINT& it) { this->_raw[it] /= norm; });
this->_dim, KOKKOS_CLASS_LAMBDA(UINT it) { this->_raw[it] /= norm; });
}

double StateVector::get_zero_probability(UINT target_qubit_index) const {
Expand All @@ -86,7 +86,7 @@ double StateVector::get_zero_probability(UINT target_qubit_index) const {
Kokkos::parallel_reduce(
"zero_prob",
_dim >> 1,
KOKKOS_CLASS_LAMBDA(const UINT& i, double& lsum) {
KOKKOS_CLASS_LAMBDA(UINT i, double& lsum) {
UINT basis_0 = internal::insert_zero_to_basis_index(i, target_qubit_index);
lsum += squared_norm(this->_raw[basis_0]);
},
Expand Down Expand Up @@ -123,7 +123,7 @@ double StateVector::get_marginal_probability(const std::vector<UINT>& measured_v
Kokkos::parallel_reduce(
"marginal_prob",
_dim >> target_index.size(),
KOKKOS_CLASS_LAMBDA(const UINT& i, double& lsum) {
KOKKOS_CLASS_LAMBDA(UINT i, double& lsum) {
UINT basis = i;
for (UINT cursor = 0; cursor < d_target_index.size(); cursor++) {
UINT insert_index = d_target_index[cursor];
Expand All @@ -143,7 +143,7 @@ double StateVector::get_entropy() const {
Kokkos::parallel_reduce(
"get_entropy",
_dim,
KOKKOS_CLASS_LAMBDA(const UINT& idx, double& lsum) {
KOKKOS_CLASS_LAMBDA(UINT idx, double& lsum) {
double prob = squared_norm(_raw[idx]);
prob = (prob > eps) ? prob : eps;
lsum += -prob * Kokkos::log(prob);
Expand All @@ -154,37 +154,36 @@ double StateVector::get_entropy() const {

void StateVector::add_state_vector(const StateVector& state) {
Kokkos::parallel_for(
this->_dim, KOKKOS_CLASS_LAMBDA(const UINT& i) { this->_raw[i] += state._raw[i]; });
this->_dim, KOKKOS_CLASS_LAMBDA(UINT i) { this->_raw[i] += state._raw[i]; });
}

void StateVector::add_state_vector_with_coef(const Complex& coef, const StateVector& state) {
Kokkos::parallel_for(
this->_dim, KOKKOS_CLASS_LAMBDA(const UINT& i) { this->_raw[i] += coef * state._raw[i]; });
this->_dim, KOKKOS_CLASS_LAMBDA(UINT i) { this->_raw[i] += coef * state._raw[i]; });
}

void StateVector::multiply_coef(const Complex& coef) {
Kokkos::parallel_for(
this->_dim, KOKKOS_CLASS_LAMBDA(const UINT& i) { this->_raw[i] *= coef; });
this->_dim, KOKKOS_CLASS_LAMBDA(UINT i) { this->_raw[i] *= coef; });
}

std::vector<UINT> StateVector::sampling(UINT sampling_count, UINT seed) const {
Kokkos::View<double*> stacked_prob("prob", _dim + 1);
Kokkos::deep_copy(stacked_prob, 0);
Kokkos::parallel_scan(
"compute_stacked_prob",
_dim,
KOKKOS_CLASS_LAMBDA(const UINT& i, double& update, const bool final) {
KOKKOS_CLASS_LAMBDA(UINT i, double& update, const bool final) {
double prob = squared_norm(this->_raw[i]);
if (final) {
stacked_prob[i + 1] = update + prob;
}
update += prob;
});

Kokkos::View<UINT*> result("result", sampling_count);
Kokkos::View<UINT*> result(Kokkos::ViewAllocateWithoutInitializing("result"), sampling_count);
Kokkos::Random_XorShift64_Pool<> rand_pool(seed);
Kokkos::parallel_for(
sampling_count, KOKKOS_LAMBDA(const UINT& i) {
sampling_count, KOKKOS_LAMBDA(UINT i) {
auto rand_gen = rand_pool.get_state();
double r = rand_gen.drand(0., 1.);
UINT lo = 0, hi = stacked_prob.size();
Expand All @@ -202,6 +201,7 @@ std::vector<UINT> StateVector::sampling(UINT sampling_count, UINT seed) const {
return internal::convert_device_view_to_host_vector<UINT>(result);
}

template <bool display_indexes>
std::string StateVector::to_string() const {
std::stringstream os;
auto amp = this->amplitudes();
Expand All @@ -210,6 +210,17 @@ std::string StateVector::to_string() const {
os << " * Dimension : " << _dim << '\n';
os << " * State vector : \n";
for (UINT i = 0; i < _dim; ++i) {
if constexpr (display_indexes) {
os <<
[](UINT n, UINT len) {
std::string tmp;
while (len--) {
tmp += ((n >> len) & 1) + '0';
}
return tmp;
}(i, _n_qubits)
<< ": ";
}
os << amp[i] << std::endl;
}
return os.str();
Expand Down
5 changes: 3 additions & 2 deletions scaluq/state/state_vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ class StateVector {
/**
* @attention Very slow. You should use load() instead if you can.
*/
void set_amplitude_at_index(const UINT& index, const Complex& c);
void set_amplitude_at_index(UINT index, const Complex& c);

/**
* @attention Very slow. You should use amplitudes() instead if you can.
*/
[[nodiscard]] Complex get_amplitude_at_index(const UINT& index) const;
[[nodiscard]] Complex get_amplitude_at_index(UINT index) const;

[[nodiscard]] static StateVector Haar_random_state(UINT n_qubits,
UINT seed = std::random_device()());
Expand Down Expand Up @@ -63,6 +63,7 @@ class StateVector {
[[nodiscard]] std::vector<UINT> sampling(UINT sampling_count,
UINT seed = std::random_device()()) const;

template <bool display_indexes = true>
[[nodiscard]] std::string to_string() const;

void load(const std::vector<Complex>& other);
Expand Down
23 changes: 10 additions & 13 deletions scaluq/util/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,17 @@ inline std::optional<ComplexMatrix> get_pauli_matrix(PauliOperator pauli) {
std::vector<UINT> pauli_id_list = pauli.get_pauli_id_list();
UINT flip_mask, phase_mask, rot90_count;
Kokkos::parallel_reduce(
pauli_id_list.size(),
KOKKOS_LAMBDA(const UINT& i, UINT& f_mask, UINT& p_mask, UINT& rot90_cnt) {
Kokkos::RangePolicy<Kokkos::DefaultHostExecutionSpace>(0, pauli_id_list.size()),
[&](UINT i, UINT& f_mask, UINT& p_mask, UINT& rot90_cnt) {
UINT pauli_id = pauli_id_list[i];
if (pauli_id == 1) {
f_mask ^= 1ULL << i;
f_mask += 1ULL << i;
} else if (pauli_id == 2) {
f_mask ^= 1ULL << i;
p_mask ^= 1ULL << i;
f_mask += 1ULL << i;
p_mask += 1ULL << i;
rot90_cnt++;
} else if (pauli_id == 3) {
p_mask ^= 1ULL << i;
p_mask += 1ULL << i;
}
},
flip_mask,
Expand All @@ -73,9 +73,8 @@ inline std::optional<ComplexMatrix> get_pauli_matrix(PauliOperator pauli) {
template <typename T>
inline Kokkos::View<T*, Kokkos::DefaultExecutionSpace> convert_host_vector_to_device_view(
const std::vector<T>& vec) {
Kokkos::fence();
Kokkos::View<T*, Kokkos::HostSpace> host_view("host_view", vec.size());
std::copy(vec.begin(), vec.end(), host_view.data());
Kokkos::View<const T*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged>> host_view(
vec.data(), vec.size());
Kokkos::View<T*, Kokkos::DefaultExecutionSpace> device_view("device_view", vec.size());
Kokkos::deep_copy(device_view, host_view);
return device_view;
Expand All @@ -84,12 +83,10 @@ inline Kokkos::View<T*, Kokkos::DefaultExecutionSpace> convert_host_vector_to_de
// Device Kokkos::View を Host std::vector に変換する関数
template <typename T>
inline std::vector<T> convert_device_view_to_host_vector(const Kokkos::View<T*>& device_view) {
Kokkos::fence();
std::vector<T> host_vector(device_view.extent(0));
Kokkos::View<T*, Kokkos::HostSpace> host_view(
Kokkos::ViewAllocateWithoutInitializing("host_view"), device_view.extent(0));
Kokkos::View<T*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged>> host_view(
host_vector.data(), host_vector.size());
Kokkos::deep_copy(host_view, device_view);
std::copy(host_view.data(), host_view.data() + host_view.extent(0), host_vector.begin());
return host_vector;
}

Expand Down

0 comments on commit bb5d1c7

Please sign in to comment.