QuIDS: Quantum Irregular Dynamic Simulator
vector.hpp
1#pragma once
2
3typedef unsigned uint;
4
5#include <iostream>
6#include <stdexcept>
7#include <iterator> // std::iterator, std::input_iterator_tag
8#include <algorithm>
9
10/* default variables preprocessor definition:
11 - "UPSIZE_POLICY" corresponds to "upsize_policy" (described in iteration_t resize operators).
12 - "DOWNSIZE_POLICY" corresponds to "downsize_policy" (described in iteration_t resize operators).
13 - "MIN_VECTOR_SIZE" corresponds to "min_state_size" which is the smallest size of a vector (described in iteration_t resize operators).
14*/
15#ifndef UPSIZE_POLICY
16 #define UPSIZE_POLICY 1.1
17#endif
18#ifndef DOWNSIZE_POLICY
19 #define DOWNSIZE_POLICY 0.85
20#endif
21#ifndef MIN_VECTOR_SIZE
22 #define MIN_VECTOR_SIZE 1000
23#endif
24
26namespace quids::utils {
27
29 float upsize_policy = UPSIZE_POLICY;
31 float downsize_policy = DOWNSIZE_POLICY;
33 size_t min_vector_size = MIN_VECTOR_SIZE;
34
36 template <typename T>
37 class fast_vector/*numa_vector*/ {
38 private:
39 mutable T* ptr = NULL;
40 mutable T* unaligned_ptr = NULL;
41 mutable size_t size_ = 0;
42
43 public:
44 template<typename Int=size_t>
45 explicit fast_vector(const Int n = 0) {
46 resize(n);
47 }
48
49 ~fast_vector() {
50 if (ptr != NULL) {
51 free(ptr);
52 ptr = NULL;
53 size_ = 0;
54 }
55 }
56
57 // NOT SUPPORTED !!!
58 size_t push_back(T) {
59 exit(0);
60 return 0;
61 }
62
63 // function that returns the popped element
64 T pop_back() {
65 return ptr[size_-- - 1];
66 }
67
68 // Function that return the size of vector
69 size_t size() const {
70 return size_;
71 }
72
73 template<typename Int=size_t>
74 T& operator[](Int index) {
75 return *(ptr + index);
76 }
77
78 template<typename Int=size_t>
79 T operator[](size_t index) const {
80 return *(ptr + index);
81 }
82
83 template<typename Int=size_t>
84 T& at(const Int index) {
85 if (index > size_) {
86 std::cerr << "index out of bound in fast vector !\n";
87 throw;
88 }
89
90 return *(ptr + index);
91 }
92
93 template<typename Int=size_t>
94 T at(const Int index) const {
95 if (index > size_) {
96 std::cerr << "index out of bound in fast vector !\n";
97 throw;
98 }
99
100 return *(ptr + index);
101 }
102
103 /*
104 "upsize_policy" is a multiplier (>1) that forces any upsize to add a margin to avoid frequent resize.
105 "downsize_policy" is a multiplier (<1) that forces a down_size to free memory only if the freed memory exceed the downsize_policy
106 (to allow memory to be freed and given back to another vector).
107 "min_state_size" is the minimum size of a vector, to avoid small vectors which are bound to be resized frequently.
108 */
110 template<typename Int=size_t>
111 void resize(const Int n_, const uint align_byte_length_=std::alignment_of<T>()) const {
112 size_t n = std::max(min_vector_size, (size_t)n_); // never resize under min_vector_size
113
114 if (size_ < n || // resize if we absolutely have to because the state won't fit
115 n*upsize_policy < size_*downsize_policy) { // resize if the size we resize to is small enough (to free memory)
116 // for later allignment
117 size_t old_size_ = size_;
118
119 size_ = n*upsize_policy;
120 int offset = std::distance(unaligned_ptr, ptr);
121 unaligned_ptr = (T*)realloc(unaligned_ptr, (size_ + align_byte_length_)*sizeof(T));
122
123 if (unaligned_ptr == NULL)
124 throw std::runtime_error("bad allocation in fast_vector !!");
125
126 ptr = unaligned_ptr + offset;
127 if (align_byte_length_ > 1) {
128 // manual allignment:
129 size_t allign_offset = ((size_t)ptr)%align_byte_length_;
130
131 if (allign_offset != 0)
132 // allign by rotating to the left:
133 if (allign_offset <= offset) {
134 std::rotate<char*>(((char*)ptr) - allign_offset, (char*)ptr, ((char*)ptr) + old_size_*sizeof(T));
135 ptr -= allign_offset;
136 } else {
137 // allign by rotating to the right
138 allign_offset = align_byte_length_ - allign_offset;
139 std::rotate<char*>((char*)ptr, ((char*)ptr) + old_size_*sizeof(T), ((char*)ptr) + old_size_*sizeof(T) + allign_offset);
140 ptr += allign_offset;
141 }
142 }
143 }
144 }
145
146 // Begin iterator
147 inline T* begin() const {
148 return ptr;
149 }
150
151 // End iterator
152 inline T* end() const {
153 return begin() + size_;
154 }
155 };
156}
drop-in replacement for vectors, with more "efficient" memory usage and access.
Definition: vector.hpp:37
void resize(const Int n_, const uint align_byte_length_=std::alignment_of< T >()) const
align_byte_length_ should be used to reallign the buffer, which is not yet implemented as realloc doe...
Definition: vector.hpp:111
QuIDS utility function and variable namespace.
Definition: algorithm.hpp:6
float downsize_policy
size multiplicator when downsize_policy, to avoid repeated upsizing. !!! upsize_policy*downsize_polic...
Definition: vector.hpp:31
float upsize_policy
size multiplicator when upsizing, to avoid repeated upsizing.
Definition: vector.hpp:29
size_t min_vector_size
minimum size a vector is allocated to (to avoid resizing at small sizes).
Definition: vector.hpp:33