TTK
Loading...
Searching...
No Matches
FTRAtomicVector.h
Go to the documentation of this file.
1
8
9#pragma once
10
11#include "BaseClass.h"
12
13#ifdef TTK_ENABLE_OPENMP
14#include <omp.h>
15#endif // TTK_ENABLE_OPENMP
16#include <iterator>
17#include <vector>
18
19#ifndef TTK_ENABLE_KAMIKAZE
20#include <iostream>
21#include <typeinfo>
22#endif
23
24namespace ttk {
25 template <typename type>
26 class FTRAtomicVector : public std::vector<type> {
27 private:
28 std::size_t nextId;
29
30 public:
31 explicit FTRAtomicVector(const std::size_t initSize = 1)
32 : std::vector<type>(), nextId(0) {
33#ifndef TTK_ENABLE_KAMIKAZE
34 if(!initSize) {
35 std::cout << "Caution, Atomic vector need a non-0 init size !"
36 << std::endl;
37 std::vector<type>::resize(initSize);
38 } else
39#endif
40 {
41 std::vector<type>::resize(initSize);
42 }
43 }
44
45 // copy constructor
47 : std::vector<type>(other), nextId(other.nextId) {
48#ifndef TTK_ENABLE_KAMIKAZE
49 if(!std::vector<type>::size()) {
50 reserve(1);
51 }
52#endif
53 }
54
55 // move constructor
56 FTRAtomicVector(FTRAtomicVector &&other) noexcept = default;
57
58 virtual ~FTRAtomicVector() = default;
59
60 // ---
61 // STL
62 // ---
63
64 void reserve(const std::size_t &newSize, const bool fromOther = false) {
65 if(newSize > std::vector<type>::size()) {
66#ifndef TTK_ENABLE_KAMIKAZE
67#ifdef TTK_ENABLE_OPENMP
68 if(omp_in_parallel()) {
69 // WARNING: In parallel we do not want to make reserve as it can lead
70 // to data race, we should not enter here
71#pragma omp critical(AtomicUFReserve)
72 {
73 // if (fromOther)
74 // std::cout << " a function in the class ";
75 // std::cout << "call RE-Reserve in FTRAtomicVector " << nextId;
76 // std::cout << " ! Data Race may occurs ! " << typeid(this).name()
77 // << std::endl;
78
79 std::vector<type>::resize(newSize);
80 }
81
82 } else
83#endif
84#endif
85 {
86 std::vector<type>::resize(newSize);
87 }
88 }
89 TTK_FORCE_USE(fromOther);
90 }
91
92 void reset(const std::size_t &nId = 0) {
93#ifdef TTK_ENABLE_OPENMP
94#pragma omp atomic write
95#endif
96 nextId = nId;
97 }
98
99 void clear() {
100 reset();
101
102 // Remove old content
103 std::size_t oldSize = std::vector<type>::size();
104 std::vector<type>::clear();
105 reserve(oldSize, true);
106 }
107
108 std::size_t getNext() {
109 std::size_t resId;
110#ifdef TTK_ENABLE_OPENMP
111#pragma omp atomic capture
112#endif
113 resId = nextId++;
114
115 if(nextId == std::vector<type>::size()) {
116 reserve(std::vector<type>::size() * 2, true);
117 }
118
119 return resId;
120 }
121
122 std::size_t size() const {
123 return nextId;
124 }
125
126 bool empty() const {
127 return nextId == 0;
128 }
129
130 void push_back(const type &elmt) {
131 const auto &curPos = getNext();
132 (*this)[curPos] = elmt;
133 }
134
135 void emplace_back(const type &elmt) {
136 // Not really constructed in place
137 // here to ensure vector compatibility
138 const auto &curPos = getNext();
139 (*this)[curPos] = elmt;
140 }
141
142 void pop_back() {
143#ifdef TTK_ENABLE_OPENMP
144#pragma omp atomic update
145#endif
146 --nextId;
147 }
148
149 // --------
150 // OPERATOR
151 // --------
152
154 if(&other != this) {
155 std::vector<type>::operator=(other);
156 nextId = other.nextId;
157 }
158 return *this;
159 }
160
162 nextId = std::move(other.nextId);
163 std::vector<type>::operator=(std::move(other));
164 return *this;
165 }
166
167 // ---------
168 // ITERATORS
169 // ---------
170 // allow foreach on the vector
171
172 using iterator = typename std::vector<type>::iterator;
173 using const_iterator = typename std::vector<type>::const_iterator;
174
176 return this->begin() + nextId;
177 }
178
180 return this->begin() + nextId;
181 }
182
184 return this->cbegin() + nextId;
185 }
186
187 using riterator = typename std::vector<type>::reverse_iterator;
188 using const_riterator = typename std::vector<type>::const_reverse_iterator;
189
191 return this->rend() - (nextId - 1);
192 }
193
195 return this->rend() - (nextId - 1);
196 }
197
199 return this->crend() - (nextId - 1);
200 }
201 };
202} // namespace ttk
#define TTK_FORCE_USE(x)
Force the compiler to use the function/method parameter.
Definition BaseClass.h:57
TTK processing package that manage a parallel version of vector Same as in FTM: Common ?
virtual ~FTRAtomicVector()=default
std::size_t size() const
void reserve(const std::size_t &newSize, const bool fromOther=false)
FTRAtomicVector< type > & operator=(const FTRAtomicVector< type > &other)
void push_back(const type &elmt)
void reset(const std::size_t &nId=0)
FTRAtomicVector(const FTRAtomicVector &other)
typename std::vector< type >::const_iterator const_iterator
const_riterator crbegin() const
FTRAtomicVector< type > & operator=(FTRAtomicVector< type > &&other) noexcept
const_riterator rbegin() const
FTRAtomicVector(const std::size_t initSize=1)
FTRAtomicVector(FTRAtomicVector &&other) noexcept=default
void emplace_back(const type &elmt)
typename std::vector< type >::const_reverse_iterator const_riterator
const_iterator end() const
typename std::vector< type >::iterator iterator
typename std::vector< type >::reverse_iterator riterator
const_iterator cend() const
The Topology ToolKit.
T begin(std::pair< T, T > &p)
Definition ripserpy.cpp:468