Quantum Gate Decomposer  v1.3
Powerful decomposition of almost any unitary into U3 and CNOT gates
matrix_base.h
Go to the documentation of this file.
1 #ifndef matrix_BASE_H
2 #define matrix_BASE_H
3 
4 #include "qgd/QGDTypes.h"
5 #include <cstring>
6 #include <iostream>
7 #include <tbb/scalable_allocator.h>
8 #include <tbb/tbb.h>
9 
10 
11 
12 
13 
14 
18 template<typename scalar>
19 class matrix_base {
20 
21 public:
23  size_t rows;
25  size_t cols;
27  scalar* data;
28 
29 protected:
30 
32  bool conjugated;
34  bool transposed;
36  bool owner;
38  tbb::spin_mutex* reference_mutex;
40  int64_t* references;
41 
42 
43 
44 public:
45 
51 
52  // The number of rows
53  rows = 0;
54  // The number of columns
55  cols = 0;
56  // pointer to the stored data
57  data = NULL;
58  // logical variable indicating whether the matrix needs to be conjugated in CBLAS operations
59  conjugated = false;
60  // logical variable indicating whether the matrix needs to be transposed in CBLAS operations
61  transposed = false;
62  // logical value indicating whether the class instance is the owner of the stored data or not. (If true, the data array is released in the destructor)
63  owner = false;
64  // mutual exclusion to count the references for class instances referring to the same data.
65  /* memory allocation new/delete in pytest call somehow fall back to malloc/free. In global pytest call this end up with invalid pointer freeing.
66  As a workaround these pointers are initialized by malloc and released by free*/
67  reference_mutex = (tbb::spin_mutex*)malloc(sizeof(tbb::spin_mutex));
68  new (reference_mutex) tbb::spin_mutex();
69  // the number of the current references of the present object
70  references = (int64_t*)malloc(sizeof(new int64_t));
71  (*references)=1;
72 }
73 
74 
82 matrix_base( scalar* data_in, size_t rows_in, size_t cols_in) {
83 
84  // The number of rows
85  rows = rows_in;
86  // The number of columns
87  cols = cols_in;
88  // pointer to the stored data
89  data = data_in;
90  // logical variable indicating whether the matrix needs to be conjugated in CBLAS operations
91  conjugated = false;
92  // logical variable indicating whether the matrix needs to be transposed in CBLAS operations
93  transposed = false;
94  // logical value indicating whether the class instance is the owner of the stored data or not. (If true, the data array is released in the destructor)
95  owner = false;
96  // mutual exclusion to count the references for class instances referring to the same data.
97  /* memory allocation new/delete in pytest call somehow fall back to malloc/free. In global pytest call this end up with invalid pointer freeing.
98  As a workaround these pointers are initialized by malloc and released by free*/
99  reference_mutex = (tbb::spin_mutex*)malloc(sizeof(tbb::spin_mutex));
100  new (reference_mutex) tbb::spin_mutex();
101  // the number of the current references of the present object
102  references = (int64_t*)malloc(sizeof(new int64_t));
103  (*references)=1;
104 }
105 
106 
107 
114 matrix_base( size_t rows_in, size_t cols_in) {
115 
116  // The number of rows
117  rows = rows_in;
118  // The number of columns
119  cols = cols_in;
120  // pointer to the stored data
121  data = (scalar*)scalable_aligned_malloc( rows*cols*sizeof(scalar), CACHELINE);
122  assert(data);
123  // logical variable indicating whether the matrix needs to be conjugated in CBLAS operations
124  conjugated = false;
125  // logical variable indicating whether the matrix needs to be transposed in CBLAS operations
126  transposed = false;
127  // logical value indicating whether the class instance is the owner of the stored data or not. (If true, the data array is released in the destructor)
128  owner = true;
129  // mutual exclusion to count the references for class instances referring to the same data.
130  /* memory allocation new/delete in pytest call somehow fall back to malloc/free. In global pytest call this end up with invalid pointer freeing.
131  As a workaround these pointers are initialized by malloc and released by free*/
132  reference_mutex = (tbb::spin_mutex*)malloc(sizeof(tbb::spin_mutex));
133  new (reference_mutex) tbb::spin_mutex();
134  // the number of the current references of the present object
135  references = (int64_t*)malloc(sizeof(new int64_t));
136  (*references)=1;
137 
138 
139 }
140 
141 
148 
149  data = in.data;
150  rows = in.rows;
151  cols = in.cols;
152  transposed = in.transposed;
153  conjugated = in.conjugated;
154  owner = in.owner;
155 
157  references = in.references;
158 
159  {
160  tbb::spin_mutex::scoped_lock my_lock{*reference_mutex};
161  (*references)++;
162  }
163 
164 
165 
166 }
167 
168 
169 
174  release_data();
175 }
176 
182  return conjugated;
183 }
184 
188 void conjugate() {
189 
191 
192 }
193 
194 
200 
201  return transposed;
202 
203 }
204 
205 
209 void transpose() {
210 
212 
213 }
214 
215 
216 
217 
221 scalar* get_data() {
222 
223  return data;
224 
225 }
226 
227 
233 void replace_data( scalar* data_in, bool owner_in) {
234 
235  release_data();
236  data = data_in;
237  owner = owner_in;
238 
239  /* memory allocation new/delete in pytest call somehow fall back to malloc/free. In global pytest call this end up with invalid pointer freeing.
240  As a workaround these pointers are initialized by malloc and released by free*/
241  reference_mutex = (tbb::spin_mutex*)malloc(sizeof(tbb::spin_mutex));
242  new (reference_mutex) tbb::spin_mutex();
243  references = (int64_t*)malloc(sizeof(new int64_t));
244  (*references)=1;
245 
246 }
247 
248 
252 void release_data() {
253 
254  if (references==NULL) return;
255  bool call_delete = false;
256 
257 {
258 
259  tbb::spin_mutex::scoped_lock my_lock{*reference_mutex};
260 
261  if (references==NULL) return;
262  call_delete = ((*references)==1);
263 
264 
265  if (call_delete) {
266  // release the data when matrix is the owner
267  if (owner) {
268  scalable_aligned_free(data);
269  }
270  free(references);
271  }
272  else {
273  (*references)--;
274  }
275 
276  data = NULL;
277  references = NULL;
278 
279 }
280 
281  if ( call_delete && reference_mutex !=NULL) {
282  reference_mutex->~spin_mutex();
283  free(reference_mutex);
284  reference_mutex=NULL;
285  }
286 
287 }
288 
289 
290 
295 void set_owner( bool owner_in) {
296 
297  owner=owner_in;
298 
299 }
300 
306 void operator= (const matrix_base& mtx ) {
307 
308  // releasing the containing data
309  release_data();
310 
311  // The number of rows
312  rows = mtx.rows;
313  // The number of columns
314  cols = mtx.cols;
315  // pointer to the stored data
316  data = mtx.data;
317  // logical variable indicating whether the matrix needs to be conjugated in CBLAS operations
318  conjugated = mtx.conjugated;
319  // logical variable indicating whether the matrix needs to be transposed in CBLAS operations
320  transposed = mtx.transposed;
321  // logical value indicating whether the class instance is the owner of the stored data or not. (If true, the data array is released in the destructor)
322  owner = mtx.owner;
323 
325  references = mtx.references;
326 
327  {
328  tbb::spin_mutex::scoped_lock my_lock{*reference_mutex};
329  (*references)++;
330  }
331 
332 }
333 
334 
340 scalar& operator[](size_t idx) {
341  return data[idx];
342 }
343 
344 
345 
346 
352 
354 
355  // logical variable indicating whether the matrix needs to be conjugated in CBLAS operations
356  ret.conjugated = conjugated;
357  // logical variable indicating whether the matrix needs to be transposed in CBLAS operations
358  ret.transposed = transposed;
359  // logical value indicating whether the class instance is the owner of the stored data or not. (If true, the data array is released in the destructor)
360  ret.owner = true;
361 
362  memcpy( ret.data, data, rows*cols*sizeof(scalar));
363 
364  return ret;
365 
366 }
367 
368 
369 
374 size_t size() {
375 
376  return rows*cols;
377 
378 }
379 
380 
384 void print_matrix() {
385  std::cout << std::endl << "The stored matrix:" << std::endl;
386  for ( size_t row_idx=0; row_idx < rows; row_idx++ ) {
387  for ( size_t col_idx=0; col_idx < cols; col_idx++ ) {
388  size_t element_idx = row_idx*cols + col_idx;
389  std::cout << " " << data[element_idx].real << " " << data[element_idx].imag << "*i";
390  }
391  std::cout << std::endl;
392  }
393  std::cout << std::endl << std::endl << std::endl;
394 
395 }
396 
397 
398 
399 
400 
401 
402 
403 }; //matrix_base
404 
405 
406 
407 
408 
409 #endif
size_t rows
The number of rows.
Definition: matrix_base.h:23
bool owner
logical value indicating whether the class instance is the owner of the stored data or not....
Definition: matrix_base.h:36
scalar * data
pointer to the stored data
Definition: matrix_base.h:27
scalar * get_data()
Call to get the pointer to the stored data.
Definition: matrix_base.h:221
void release_data()
Call to release the data stored by the matrix.
Definition: matrix_base.h:252
bool transposed
logical variable indicating whether the matrix needs to be transposed in CBLAS operations
Definition: matrix_base.h:34
bool conjugated
logical variable indicating whether the matrix needs to be conjugated in CBLAS operations
Definition: matrix_base.h:32
~matrix_base()
Destructor of the class.
Definition: matrix_base.h:173
#define CACHELINE
Definition: QGDTypes.h:34
bool is_conjugated()
Call to get whether the matrix should be conjugated in CBLAS functions or not.
Definition: matrix_base.h:181
Base Class to store data of arrays and its properties.
Definition: matrix_base.h:19
void operator=(const matrix_base &mtx)
Assignment operator.
Definition: matrix_base.h:306
size_t cols
The number of columns.
Definition: matrix_base.h:25
matrix_base(size_t rows_in, size_t cols_in)
Constructor of the class.
Definition: matrix_base.h:114
void replace_data(scalar *data_in, bool owner_in)
Call to replace the stored data by an another data array.
Definition: matrix_base.h:233
Custom types for the QGD package.
void set_owner(bool owner_in)
Call to set the current class instance to be (or not to be) the owner of the stored data array.
Definition: matrix_base.h:295
void print_matrix()
Call to prints the stored matrix on the standard output.
Definition: matrix_base.h:384
void transpose()
Call to transpose (or un-transpose) the matrix for CBLAS functions.
Definition: matrix_base.h:209
matrix_base()
Default constructor of the class.
Definition: matrix_base.h:50
matrix_base< scalar > copy()
Call to create a copy of the matrix.
Definition: matrix_base.h:351
scalar & operator[](size_t idx)
Operator [] to access elements in array style (does not check the boundaries of the stored array)
Definition: matrix_base.h:340
void conjugate()
Call to conjugate (or un-conjugate) the matrix for CBLAS functions.
Definition: matrix_base.h:188
matrix_base(const matrix_base< scalar > &in)
Copy constructor of the class.
Definition: matrix_base.h:147
int64_t * references
the number of the current references of the present object
Definition: matrix_base.h:40
size_t size()
Call to get the number of the allocated elements.
Definition: matrix_base.h:374
matrix_base(scalar *data_in, size_t rows_in, size_t cols_in)
Constructor of the class.
Definition: matrix_base.h:82
tbb::spin_mutex * reference_mutex
mutual exclusion to count the references for class instances referring to the same data.
Definition: matrix_base.h:38
bool is_transposed()
Call to get whether the matrix should be conjugated in CBLAS functions or not.
Definition: matrix_base.h:199