state_gpu.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "state.hpp"
4 
5 #ifdef _USE_GPU
6 
7 #include <gpusim/update_ops_cuda.h>
8 #include <gpusim/memory_ops.h>
9 #include <gpusim/stat_ops.h>
10 #include <gpusim/util_func.h>
11 
12 class QuantumStateGpu : public QuantumStateBase {
13 private:
14  void* _state_vector; // void* is assumed as GTYPE*
15  Random random;
16 public:
22  QuantumStateGpu(UINT qubit_count_) : QuantumStateBase(qubit_count_, true) {
23  this->_state_vector = reinterpret_cast<void*>(allocate_quantum_state_host(this->_dim));
24  initialize_quantum_state_host(this->data(), _dim);
25  }
29  virtual ~QuantumStateGpu() {
30  release_quantum_state_host(this->data());
31  }
35  virtual void set_zero_state() override {
36  initialize_quantum_state_host(this->data(), _dim);
37  }
43  virtual void set_computational_basis(ITYPE comp_basis) override {
44  set_computational_basis_host(comp_basis, _state_vector, _dim);
45  }
49  virtual void set_Haar_random_state() override {
50  initialize_Haar_random_state_with_seed_host(this->data(), _dim, random.int32());
51  }
55  virtual void set_Haar_random_state(UINT seed) override {
56  initialize_Haar_random_state_with_seed_host(this->data(), _dim, seed);
57  }
65  virtual double get_zero_probability(UINT target_qubit_index) const override {
66  return M0_prob_host(target_qubit_index, this->data(), _dim);
67  }
74  virtual double get_marginal_probability(std::vector<UINT> measured_values) const override {
75  std::vector<UINT> target_index;
76  std::vector<UINT> target_value;
77  for (UINT i = 0; i < measured_values.size(); ++i) {
78  UINT measured_value = measured_values[i];
79  if (measured_value == 0 || measured_value == 1) {
80  target_index.push_back(i);
81  target_value.push_back(measured_value);
82  }
83  }
84  return marginal_prob_host(target_index.data(), target_value.data(), (UINT)target_index.size(), this->data(), _dim);
85  }
91  virtual double get_entropy() const override {
92  return measurement_distribution_entropy_host(this->data(), _dim);
93  }
94 
101  virtual double get_norm() const override {
102  return state_norm_host(this->data(), _dim);
103  }
104 
110  virtual void normalize(double norm) override {
111  normalize_host(norm, this->data(), _dim);
112  }
113 
114 
120  virtual QuantumStateBase* allocate_buffer() const override {
121  QuantumStateGpu* new_state = new QuantumStateGpu(this->_qubit_count);
122  return new_state;
123  }
129  virtual QuantumStateBase* copy() const override {
130  QuantumStateGpu* new_state = new QuantumStateGpu(this->_qubit_count);
131  copy_quantum_state_from_device_to_device(new_state->data(), _state_vector, _dim);
132  return new_state;
133  }
137  virtual void load(const QuantumStateBase* _state) override {
138  if (_state->get_device_name() == "gpu") {
139  copy_quantum_state_from_device_to_device(this->data(), _state->data(), dim);
140  }
141  else {
142  this->load(_state->data_cpp());
143  }
144  this->_classical_register = _state->classical_register;
145  }
146 
150  virtual void load(const std::vector<CPPCTYPE>& _state) override{
151  copy_quantum_state_from_cppstate_host(this->data(), _state.data(), dim);
152  }
153 
157  virtual void load(const CPPCTYPE* _state) override{
158  copy_quantum_state_from_cppstate_host(this->data(), _state, dim);
159  }
163  virtual const std::string get_device_name() const override { return "gpu"; }
164 
170  virtual CPPCTYPE* data_cpp() const override {
171  CPPCTYPE* _copy_state = (CPPCTYPE*)malloc(sizeof(CPPCTYPE)*dim);
172  get_quantum_state_host(this->_state_vector,_copy_state, dim);
173  return _copy_state;
174  }
175 
181  virtual CTYPE* data_c() const override {
182  CTYPE* _copy_state = (CTYPE*)malloc(sizeof(CTYPE)*dim);
183  get_quantum_state_host(this->_state_vector, _copy_state, dim);
184  return _copy_state;
185  }
186 
192  virtual void* data() const override {
193  return reinterpret_cast<void*>(this->_state_vector);
194  }
195 
196 
200  virtual void add_state(const QuantumStateBase* state) override{
201  state_add_host(state->data(), this->data(), this->dim);
202  }
206  virtual void multiply_coef(CPPCTYPE coef) override{
207  state_multiply_host(coef, this->data(), this->dim);
208  }
209 
210 
211 
218  virtual std::vector<ITYPE> sampling(UINT sampling_count) override {
219  std::vector<double> stacked_prob;
220  std::vector<ITYPE> result;
221  double sum = 0.;
222  auto ptr = this->data_cpp();
223  stacked_prob.push_back(0.);
224  for (UINT i = 0; i < this->dim; ++i) {
225  sum += norm(ptr[i]);
226  stacked_prob.push_back(sum);
227  }
228 
229  for (UINT count = 0; count < sampling_count; ++count) {
230  double r = random.uniform();
231  auto ite = std::lower_bound(stacked_prob.begin(), stacked_prob.end(), r);
232  auto index = std::distance(stacked_prob.begin(), ite) - 1;
233  result.push_back(index);
234  }
235  free(ptr);
236  return result;
237  }
238 };
239 
240 namespace state {
248  CPPCTYPE DllExport inner_product(const QuantumStateGpu* state_bra, const QuantumStateGpu* state_ket) {
249  return inner_product_host(state_bra->data(), state_ket->data(), state_ket->dim);
250  }
251 }
252 
253 #endif // _USE_GPU
virtual double get_zero_probability(UINT target_qubit_index) const =0
#define DllExport
Definition: type.hpp:32
CPPCTYPE inner_product(const QuantumState *state1, const QuantumState *state2)
Definition: state.cpp:16
virtual void load(const QuantumStateBase *state)=0
virtual CTYPE * data_c() const =0
Definition: utility.hpp:51
virtual const std::string get_device_name() const =0
virtual void set_Haar_random_state()=0
virtual void add_state(const QuantumStateBase *state)=0
virtual std::vector< ITYPE > sampling(UINT sampling_count)=0
std::complex< double > CPPCTYPE
Definition: type.hpp:14
Definition: state.hpp:24
virtual void set_computational_basis(ITYPE comp_basis)=0
virtual CPPCTYPE * data_cpp() const =0
virtual double get_norm() const =0
const std::vector< UINT > & classical_register
Definition: state.hpp:33
const ITYPE & dim
Definition: state.hpp:32
virtual QuantumStateBase * copy() const =0
Definition: state.cpp:15
virtual QuantumStateBase * allocate_buffer() const =0
virtual void multiply_coef(CPPCTYPE coef)=0
virtual void set_zero_state()=0
unsigned long int32()
Definition: utility.hpp:99
virtual void normalize(double norm)=0
virtual double get_entropy() const =0
double uniform()
Definition: utility.hpp:78
virtual void * data() const =0
ITYPE _dim
Definition: state.hpp:26
virtual double get_marginal_probability(std::vector< UINT > measured_values) const =0