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_squared_norm() const override {
102  return state_norm_squared_host(this->data(), _dim);
103  }
104 
110  virtual void normalize(double squared_norm) override {
111  normalize_host(squared_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  std::cerr << "Cannot reinterpret state vector on GPU to cpp complex vector. Use duplicate_data_cpp instead." << std::endl;
172  return NULL;
173  }
174 
180  virtual CTYPE* data_c() const override {
181  std::cerr << "Cannot reinterpret state vector on GPU to C complex vector. Use duplicate_data_cpp instead." << std::endl;
182  return NULL;
183  }
184 
190  virtual void* data() const override {
191  return reinterpret_cast<void*>(this->_state_vector);
192  }
193 
194  virtual CTYPE* duplicate_data_c() const override {
195  CTYPE* _copy_state = (CTYPE*)malloc(sizeof(CTYPE)*dim);
196  get_quantum_state_host(this->_state_vector, _copy_state, dim);
197  return _copy_state;
198  }
199 
200  virtual CPPCTYPE* duplicate_data_cpp() const override {
201  CPPCTYPE* _copy_state = (CPPCTYPE*)malloc(sizeof(CPPCTYPE)*dim);
202  get_quantum_state_host(this->_state_vector, _copy_state, dim);
203  return _copy_state;
204  }
205 
209  virtual void add_state(const QuantumStateBase* state) override{
210  state_add_host(state->data(), this->data(), this->dim);
211  }
215  virtual void multiply_coef(CPPCTYPE coef) override{
216  state_multiply_host(coef, this->data(), this->dim);
217  }
218 
219 
220 
227  virtual std::vector<ITYPE> sampling(UINT sampling_count) override {
228  std::vector<double> stacked_prob;
229  std::vector<ITYPE> result;
230  double sum = 0.;
231  auto ptr = this->duplicate_data_cpp();
232  stacked_prob.push_back(0.);
233  for (UINT i = 0; i < this->dim; ++i) {
234  sum += norm(ptr[i]);
235  stacked_prob.push_back(sum);
236  }
237 
238  for (UINT count = 0; count < sampling_count; ++count) {
239  double r = random.uniform();
240  auto ite = std::lower_bound(stacked_prob.begin(), stacked_prob.end(), r);
241  auto index = std::distance(stacked_prob.begin(), ite) - 1;
242  result.push_back(index);
243  }
244  free(ptr);
245  return result;
246  }
247 
248  virtual std::string to_string() const {
249  std::stringstream os;
250  ComplexVector eigen_state(this->dim);
251  auto data = this->duplicate_data_cpp();
252  for (UINT i = 0; i < this->dim; ++i) eigen_state[i] = data[i];
253  os << " *** Quantum State ***" << std::endl;
254  os << " * Qubit Count : " << this->qubit_count << std::endl;
255  os << " * Dimension : " << this->dim << std::endl;
256  os << " * State vector : \n" << eigen_state << std::endl;
257  free(data);
258  return os.str();
259  }
260 };
261 
262 namespace state {
270  CPPCTYPE DllExport inner_product(const QuantumStateGpu* state_bra, const QuantumStateGpu* state_ket);
271 }
272 
273 #endif // _USE_GPU
Eigen::VectorXcd ComplexVector
Definition: type.hpp:15
virtual double get_zero_probability(UINT target_qubit_index) const =0
#define DllExport
Definition: type.hpp:38
CPPCTYPE inner_product(const QuantumState *state1, const QuantumState *state2)
Definition: state.cpp:16
virtual CPPCTYPE * duplicate_data_cpp() const =0
virtual void load(const QuantumStateBase *state)=0
virtual CTYPE * data_c() const =0
virtual std::string to_string() const
Definition: state.hpp:245
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:26
virtual void set_computational_basis(ITYPE comp_basis)=0
virtual CPPCTYPE * data_cpp() const =0
virtual CTYPE * duplicate_data_c() const =0
const std::vector< UINT > & classical_register
Definition: state.hpp:35
const ITYPE & dim
Definition: state.hpp:34
virtual void normalize(double squared_norm)=0
virtual QuantumStateBase * copy() const =0
Definition: state.cpp:15
virtual QuantumStateBase * allocate_buffer() const =0
virtual double get_squared_norm() const =0
virtual void multiply_coef(CPPCTYPE coef)=0
virtual void set_zero_state()=0
unsigned long int32()
Definition: utility.hpp:99
virtual double get_entropy() const =0
double uniform()
Definition: utility.hpp:78
virtual void * data() const =0
ITYPE _dim
Definition: state.hpp:28
virtual double get_marginal_probability(std::vector< UINT > measured_values) const =0