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_) {
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_host(new_state->data(), _state_vector, _dim);
132  return new_state;
133  }
137  virtual void load(const QuantumStateBase* _state) override{
138  copy_quantum_state_host(this->data(), _state->data(), dim);
139  }
140 
144  virtual void load(const std::vector<CPPCTYPE>& _state) override{
145  copy_quantum_state_from_cppstate_host(this->data(), _state.data(), dim);
146  }
147 
151  virtual void load(const CPPCTYPE* _state) override{
152  copy_quantum_state_from_cppstate_host(this->data(), _state, dim);
153  }
157  virtual const std::string get_device_name() const override { return "gpu"; }
158 
164  virtual CPPCTYPE* data_cpp() const override {
165  CPPCTYPE* _copy_state = (CPPCTYPE*)malloc(sizeof(CPPCTYPE)*dim);
166  get_quantum_state_host(this->_state_vector,_copy_state, dim);
167  return _copy_state;
168  }
169 
175  virtual CTYPE* data_c() const override {
176  CTYPE* _copy_state = (CTYPE*)malloc(sizeof(CTYPE)*dim);
177  get_quantum_state_host(this->_state_vector, _copy_state, dim);
178  return _copy_state;
179  }
180 
186  virtual void* data() const override {
187  return reinterpret_cast<void*>(this->_state_vector);
188  }
189 
190 
194  virtual void add_state(const QuantumStateBase* state) override{
195  state_add_host(state->data(), this->data(), this->dim);
196  }
200  virtual void multiply_coef(CPPCTYPE coef) override{
201  state_multiply_host(coef, this->data(), this->dim);
202  }
203 
204 
205 
212  virtual std::vector<ITYPE> sampling(UINT sampling_count) override {
213  std::vector<double> stacked_prob;
214  std::vector<ITYPE> result;
215  double sum = 0.;
216  auto ptr = this->data_cpp();
217  stacked_prob.push_back(0.);
218  for (UINT i = 0; i < this->dim; ++i) {
219  sum += norm(ptr[i]);
220  stacked_prob.push_back(sum);
221  }
222 
223  for (UINT count = 0; count < sampling_count; ++count) {
224  double r = random.uniform();
225  auto ite = std::lower_bound(stacked_prob.begin(), stacked_prob.end(), r);
226  auto index = std::distance(stacked_prob.begin(), ite) - 1;
227  result.push_back(index);
228  }
229  return result;
230  }
231 };
232 
233 namespace state {
241  //CPPCTYPE DllExport inner_product(const QuantumStateGpu* state_bra, const QuantumStateGpu* state_ket) {
242  // return inner_product_host(state_bra, state_ket, state_ket->dim);
243  //}
244 }
245 
246 #endif // _USE_GPU
virtual double get_zero_probability(UINT target_qubit_index) const =0
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 ITYPE & dim
Definition: state.hpp:31
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