Sequential Quantum Gate Decomposer  v1.9.3
Powerful decomposition of general unitarias into one- and two-qubit gates gates
matrix_base.hpp
Go to the documentation of this file.
1 /*
2 Copyright 2020 Peter Rakyta, Ph.D.
3 
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 
16 */
17 
18 #ifndef matrix_BASE_H
19 #define matrix_BASE_H
20 
21 #include "QGDTypes.h"
22 #include <cstring>
23 #include <iostream>
24 #include <tbb/scalable_allocator.h>
25 #include <tbb/spin_mutex.h>
26 
27 
28 
37 template<typename scalar>
38 class matrix_base {
39 
40 public:
42  int rows;
44  int cols;
46  int stride;
49 
50 protected:
51 
53  bool conjugated;
55  bool transposed;
57  bool owner;
59  tbb::spin_mutex* reference_mutex;
61  int64_t* references;
62 
63 
64 
65 public:
66 
72 
73  // The number of rows
74  rows = 0;
75  // The number of columns
76  cols = 0;
77  // The column stride of the matrix
78  stride = 0;
79  // pointer to the stored data
80  data = NULL;
81  // logical variable indicating whether the matrix needs to be conjugated in CBLAS operations
82  conjugated = false;
83  // logical variable indicating whether the matrix needs to be transposed in CBLAS operations
84  transposed = false;
85  // 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)
86  owner = false;
87  // mutual exclusion to count the references for class instances referring to the same data.
88  reference_mutex = new tbb::spin_mutex();
89  references = new int64_t;
90  (*references)=1;
91 }
92 
93 
101 matrix_base( scalar* data_in, int rows_in, int cols_in) {
102 
103  // The number of rows
104  rows = rows_in;
105  // The number of columns
106  cols = cols_in;
107  // The column stride of the matrix
108  stride = cols_in;
109  // pointer to the stored data
110  data = data_in;
111  // logical variable indicating whether the matrix needs to be conjugated in CBLAS operations
112  conjugated = false;
113  // logical variable indicating whether the matrix needs to be transposed in CBLAS operations
114  transposed = false;
115  // 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)
116  owner = false;
117  // mutual exclusion to count the references for class instances referring to the same data.
118  reference_mutex = new tbb::spin_mutex();
119  references = new int64_t;
120  (*references)=1;
121 }
122 
123 
124 
133 matrix_base( scalar* data_in, int rows_in, int cols_in, int stride_in) {
134 
135  // The number of rows
136  rows = rows_in;
137  // The number of columns
138  cols = cols_in;
139  // The column stride of the matrix
140  stride = stride_in;
141  // pointer to the stored data
142  data = data_in;
143  // logical variable indicating whether the matrix needs to be conjugated in CBLAS operations
144  conjugated = false;
145  // logical variable indicating whether the matrix needs to be transposed in CBLAS operations
146  transposed = false;
147  // 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)
148  owner = false;
149  // mutual exclusion to count the references for class instances referring to the same data.
150  reference_mutex = new tbb::spin_mutex();
151  references = new int64_t;
152  (*references)=1;
153 }
154 
155 
156 
163 matrix_base( int rows_in, int cols_in) {
164 
165  // The number of rows
166  rows = rows_in;
167  // The number of columns
168  cols = cols_in;
169  // The column stride of the matrix
170  stride = cols_in;
171  // pointer to the stored data
172  data = (scalar*)scalable_aligned_malloc( rows*cols*sizeof(scalar), CACHELINE);
173  assert(data);
174  // logical variable indicating whether the matrix needs to be conjugated in CBLAS operations
175  conjugated = false;
176  // logical variable indicating whether the matrix needs to be transposed in CBLAS operations
177  transposed = false;
178  // 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)
179  owner = true;
180  // mutual exclusion to count the references for class instances referring to the same data.
181  reference_mutex = new tbb::spin_mutex();
182  references = new int64_t;
183  (*references)=1;
184 
185 
186 }
187 
188 
196 matrix_base( int rows_in, int cols_in, int stride_in) {
197 
198  // The number of rows
199  rows = rows_in;
200  // The number of columns
201  cols = cols_in;
202  // The column stride of the matrix
203  stride = stride_in;
204  // pointer to the stored data
205  data = (scalar*)scalable_aligned_malloc( rows*stride*sizeof(scalar), CACHELINE);
206 #ifdef DEBUG
207  if (rows > 0 && cols>0) assert(data);
208 #endif
209  // logical variable indicating whether the matrix needs to be conjugated in CBLAS operations
210  conjugated = false;
211  // logical variable indicating whether the matrix needs to be transposed in CBLAS operations
212  transposed = false;
213  // 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)
214  owner = true;
215  // mutual exclusion to count the references for class instances referring to the same data.
216  reference_mutex = new tbb::spin_mutex();
217  references = new int64_t;
218  (*references)=1;
219 
220 
221 }
222 
223 
230 
231  data = in.data;
232  rows = in.rows;
233  cols = in.cols;
234  stride = in.stride;
235  transposed = in.transposed;
236  conjugated = in.conjugated;
237  owner = in.owner;
238 
239  reference_mutex = in.reference_mutex;
240  references = in.references;
241 
242  {
243  tbb::spin_mutex::scoped_lock my_lock{*reference_mutex};
244  (*references)++;
245  }
246 
247 
248 
249 }
250 
251 
252 
257  release_data();
258 }
259 
265  return conjugated;
266 }
267 
271 void conjugate() {
272 
273  conjugated = !conjugated;
274 
275 }
276 
277 
283 
284  return transposed;
285 
286 }
287 
288 
292 void transpose() {
293 
294  transposed = !transposed;
295 
296 }
297 
298 
299 
300 
304 scalar* get_data() const {
305 
306  return data;
307 
308 }
309 
310 
316 void replace_data( scalar* data_in, bool owner_in) {
317 
318  release_data();
319  data = data_in;
320  owner = owner_in;
321 
322  // mutual exclusion to count the references for class instances referring to the same data.
323  reference_mutex = new tbb::spin_mutex();
324  references = new int64_t;
325  (*references)=1;
326 
327 }
328 
329 
333 void release_data() {
334 
335  if (references==NULL) return;
336  bool call_delete = false;
337 
338 {
339 
340  tbb::spin_mutex::scoped_lock my_lock{*reference_mutex};
341 
342  if (references==NULL) return;
343  call_delete = ((*references)==1);
344 
345 
346  if (call_delete) {
347  // release the data when matrix is the owner
348  if (owner) {
349  scalable_aligned_free(data);
350  }
351  delete references;
352  }
353  else {
354  (*references)--;
355  }
356 
357  data = NULL;
358  references = NULL;
359 
360 }
361 
362  if ( call_delete && reference_mutex !=NULL) {
363  reference_mutex->~spin_mutex();
364  delete reference_mutex;
365  reference_mutex=NULL;
366  }
367 
368 }
369 
370 
371 
376 void set_owner( bool owner_in) {
377 
378  owner=owner_in;
379 
380 }
381 
387 void operator= (const matrix_base& mtx ) {
388 
389  // releasing the containing data
390  release_data();
391 
392  // The number of rows
393  rows = mtx.rows;
394  // The number of columns
395  cols = mtx.cols;
396  // The column stride of the matrix
397  stride = mtx.stride;
398  // pointer to the stored data
399  data = mtx.data;
400  // logical variable indicating whether the matrix needs to be conjugated in CBLAS operations
401  conjugated = mtx.conjugated;
402  // logical variable indicating whether the matrix needs to be transposed in CBLAS operations
403  transposed = mtx.transposed;
404  // 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)
405  owner = mtx.owner;
406 
407  reference_mutex = mtx.reference_mutex;
408  references = mtx.references;
409 
410  {
411  tbb::spin_mutex::scoped_lock my_lock{*reference_mutex};
412  (*references)++;
413  }
414 
415 }
416 
417 
423 scalar& operator[](int idx) const {
424 
425 #ifdef DEBUG
426  if ( idx >= rows*stride || idx < 0) {
427  std::cout << "Accessing element out of bonds. Exiting" << std::endl;
428  exit(-1);
429  }
430 #endif
431 
432  return data[idx];
433 }
434 
435 
441 
443 
444  // logical variable indicating whether the matrix needs to be conjugated in CBLAS operations
445  ret.conjugated = conjugated;
446  // logical variable indicating whether the matrix needs to be transposed in CBLAS operations
447  ret.transposed = transposed;
448  // 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)
449  ret.owner = true;
450 
451  memcpy( ret.data, data, rows*stride*sizeof(scalar));
452 
453  return ret;
454 
455 }
456 
458  if (((uintptr_t)(void*)data & (CACHELINE-1)) == 0) return; //CACHELINE must be power of 2, 16 sufficient, 64 is okay though
459  scalar* newdata = (scalar*)scalable_aligned_malloc( rows*stride*sizeof(scalar), CACHELINE);
460  memcpy( newdata, data, rows*stride*sizeof(scalar));
461  replace_data(newdata, true);
462 }
463 
464 
465 
470 int size() const {
471 
472  return rows*cols;
473 
474 }
475 
476 
480 void print_matrix() const {
481  std::cout << std::endl << "The stored matrix:" << std::endl;
482  for ( int row_idx=0; row_idx < rows; row_idx++ ) {
483  for ( int col_idx=0; col_idx < cols; col_idx++ ) {
484  int element_idx = row_idx*stride + col_idx;
485  std::cout << " " << data[element_idx];
486  }
487  std::cout << std::endl;
488  }
489  std::cout << std::endl << std::endl << std::endl;
490 
491 }
492 
493 
494 
495 
496 
497 
498 
499 }; //matrix_base
500 
501 
502 
503 
504 
505 #endif
bool owner
logical value indicating whether the class instance is the owner of the stored data or not...
Definition: matrix_base.hpp:57
int stride
The column stride of the array. (The array elements in one row are a_0, a_1, ... a_{cols-1}, 0, 0, 0, 0. The number of zeros is stride-cols)
Definition: matrix_base.hpp:46
matrix_base< scalar > copy() const
Call to create a copy of the matrix.
scalar * data
pointer to the stored data
Definition: matrix_base.hpp:48
matrix_base(scalar *data_in, int rows_in, int cols_in)
Constructor of the class.
void release_data()
Call to release the data stored by the matrix.
void ensure_aligned()
matrix_base(scalar *data_in, int rows_in, int cols_in, int stride_in)
Constructor of the class.
bool transposed
logical variable indicating whether the matrix needs to be transposed in CBLAS operations ...
Definition: matrix_base.hpp:55
bool conjugated
logical variable indicating whether the matrix needs to be conjugated in CBLAS operations ...
Definition: matrix_base.hpp:53
scalar * get_data() const
Call to get the pointer to the stored data.
~matrix_base()
Destructor of the class.
#define CACHELINE
Definition: QGDTypes.h:33
bool is_conjugated()
Call to get whether the matrix should be conjugated in CBLAS functions or not.
Base Class to store data of arrays and its properties.
Definition: matrix_base.hpp:38
void operator=(const matrix_base &mtx)
Assignment operator.
scalar & operator[](int idx) const
Operator [] to access elements in array style (does not check the boundaries of the stored array) ...
int rows
The number of rows.
Definition: matrix_base.hpp:42
int cols
The number of columns.
Definition: matrix_base.hpp:44
void replace_data(scalar *data_in, bool owner_in)
Call to replace the stored data by an another data array.
matrix_base(int rows_in, int cols_in, int stride_in)
Constructor of the class.
Custom types for the SQUANDER package.
void print_matrix() const
Call to prints the stored matrix on the standard output.
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...
int size() const
Call to get the number of the allocated elements.
void transpose()
Call to transpose (or un-transpose) the matrix for CBLAS functions.
matrix_base()
Default constructor of the class.
Definition: matrix_base.hpp:71
matrix_base(int rows_in, int cols_in)
Constructor of the class.
void conjugate()
Call to conjugate (or un-conjugate) the matrix for CBLAS functions.
matrix_base(const matrix_base< scalar > &in)
Copy constructor of the class.
int64_t * references
the number of the current references of the present object
Definition: matrix_base.hpp:61
tbb::spin_mutex * reference_mutex
mutual exclusion to count the references for class instances referring to the same data...
Definition: matrix_base.hpp:59
bool is_transposed()
Call to get whether the matrix should be conjugated in CBLAS functions or not.