View on GitHub

Vistle

Distributed Data-parallel Scientific Visualization in VR

shm_array.h
Go to the documentation of this file.
1#ifndef SHM_ARRAY_H
2#define SHM_ARRAY_H
3
4#include <cassert>
5#include <atomic>
6#include <cstring>
7#include <type_traits>
8
10#include <vistle/util/tools.h>
11#include "export.h"
12#include "index.h"
13#include "archives_config.h"
14#include "shmdata.h"
15
16namespace vistle {
17
18template<typename T, class allocator>
19class shm_array: public ShmData {
20public:
21 typedef T value_type;
22 typedef uint64_t size_type;
24
25 static int typeId();
26
27 shm_array(const allocator &alloc = allocator())
28 : ShmData(ShmData::ARRAY), m_type(typeId()), m_size(0), m_capacity(0), m_data(nullptr), m_allocator(alloc)
29 {
30 resize(0);
31 }
32
33 shm_array(const size_t size, const allocator &alloc = allocator())
34 : ShmData(ShmData::ARRAY), m_type(typeId()), m_size(0), m_capacity(0), m_data(nullptr), m_allocator(alloc)
35 {
36 resize(size);
37 }
38
39 shm_array(const size_t size, const T &value, const allocator &alloc = allocator())
40 : ShmData(ShmData::ARRAY), m_type(typeId()), m_size(0), m_capacity(0), m_data(nullptr), m_allocator(alloc)
41 {
42 resize(size, value);
43 }
44
47 , m_type(other.m_type)
48 , m_size(other.m_size)
49 , m_capacity(other.m_capacity)
50 , m_data(other.m_data)
51 , m_allocator(other.m_allocator)
52 {
53 other.m_data = nullptr;
54 other.m_size = 0;
55 other.m_capacity = 0;
56 assert(typeId() == m_type);
57 }
58
60 {
61 assert(refcount() == 0);
63 }
64
65 int type() const { return m_type; }
66 bool check() const
67 {
68 assert(refcount() >= 0);
69 assert(m_size <= m_capacity);
70 if (refcount() < 0) {
71 std::cerr << "shm_array: INCONSISTENCY: refcount() < 0" << std::endl;
72 return false;
73 }
74 if (m_size > m_capacity) {
75 std::cerr << "shm_array: INCONSISTENCY: m_size > m_capacity" << std::endl;
76 return false;
77 }
78 if (m_dim[0] != 0 && m_size != m_dim[0] * m_dim[1] * m_dim[2]) {
79 std::cerr << "shm_array: INCONSISTENCY: dimensions" << std::endl;
80 return false;
81 }
82 return true;
83 }
84
85 typedef typename allocator::pointer pointer;
86 typedef T *iterator;
87 typedef const T *const_iterator;
88
89 iterator begin() const { return &*m_data; }
90 iterator end() const { return (&*m_data) + m_size; }
91 T *data() const { return &*m_data; }
92
93 T &operator[](const size_t idx) { return m_data[idx]; }
94 T &operator[](const size_t idx) const { return m_data[idx]; }
95 T &at(const size_t idx)
96 {
97 if (idx >= m_size)
98 throw(std::out_of_range("shm_array"));
99 return m_data[idx];
100 }
101 T &at(const size_t idx) const
102 {
103 if (idx >= m_size)
104 throw(std::out_of_range("shm_array"));
105 return m_data[idx];
106 }
107
108 void push_back(const T &v)
109 {
110 if (m_size >= m_capacity)
111 reserve(m_capacity == 0 ? 1 : m_capacity * 2);
112 assert(m_size < m_capacity);
113 new (&m_data[m_size]) T(v);
114 ++m_size;
115 }
116
117 template<class... Args>
118 void emplace_back(Args &&...args)
119 {
120 if (m_size >= m_capacity)
121 reserve(m_capacity == 0 ? 1 : m_capacity * 2);
122 assert(m_size < m_capacity);
123 new (&m_data[m_size]) T(std::forward<Args>(args)...);
124 ++m_size;
125 }
126
127 T &back() { return m_data[m_size - 1]; }
128 T &front() { return m_data[0]; }
129
130 bool empty() const { return m_size == 0; }
131 void clear() { resize(0); }
132
133 size_t size() const { return m_size; }
134 void resize(const size_t size)
135 {
136 reserve(size);
137 if (!std::is_trivially_copyable<T>::value) {
138 for (size_t i = m_size; i < size; ++i)
139 new (&m_data[i]) T();
140 }
141 m_size = size;
142 assert(m_size <= m_capacity);
144 }
145 void resize(const size_t size, const T &value)
146 {
147 reserve(size);
148 for (size_t i = m_size; i < size; ++i)
149 new (&m_data[i]) T(value);
150 m_size = size;
151 assert(m_size <= m_capacity);
153 }
154
156 {
157 m_dim[0] = 0;
158 m_dim[1] = m_dim[2] = 1;
159 }
160 void setDimensionHint(const size_t sx, const size_t sy = 1, const size_t sz = 1)
161 {
162 assert(m_size == sx * sy * sz);
163 m_dim[0] = sx;
164 m_dim[1] = sy;
165 m_dim[2] = sz;
166 }
167 void setExact(bool exact) { m_exact = exact; }
168
169 size_t capacity() const { return m_capacity; }
170 void reserve(const size_t new_capacity)
171 {
172 if (new_capacity > capacity())
173 reserve_or_shrink(new_capacity);
174 }
175 void reserve_or_shrink(const size_t capacity)
176 {
177 pointer new_data = capacity > 0 ? m_allocator.allocate(capacity) : nullptr;
178 const size_t n = capacity < m_size ? capacity : m_size;
179 if (m_data && new_data) {
180 if (std::is_trivially_copyable<T>::value) {
181 ::memcpy(&*new_data, &*m_data, sizeof(T) * n);
182 } else {
183 for (size_t i = 0; i < n; ++i) {
184 new (&new_data[i]) T(std::move(m_data[i]));
185 }
186 }
187 }
188 if (m_data) {
189 if (!std::is_trivially_copyable<T>::value) {
190 for (size_t i = n; i < m_size; ++i) {
191 m_data[i].~T();
192 }
193 }
194 m_allocator.deallocate(m_data, m_capacity);
195 }
196 m_data = new_data;
197 m_capacity = capacity;
198 }
200 {
201 reserve_or_shrink(m_size);
202 assert(m_capacity == m_size);
203 }
204
205private:
206 const uint32_t m_type;
207 size_t m_size = 0;
208 size_t m_dim[3] = {0, 1, 1};
209 size_t m_capacity = 0;
210 bool m_exact = std::is_integral<T>::value;
211 pointer m_data;
212 allocator m_allocator;
213
215 template<class Archive>
216 void save(Archive &ar) const;
217 template<class Archive>
218 void load(Archive &ar);
219
220 // not implemented
221 shm_array(const shm_array &other) = delete;
222 shm_array &operator=(const shm_array &rhs) = delete;
223};
224
225} // namespace vistle
226#endif
227
228#ifndef SHM_ARRAY_IMPL_H
229#define SHM_ARRAY_IMPL_H
230
231namespace vistle {
232
233template<typename T, class allocator>
234template<class Archive>
235void shm_array<T, allocator>::save(Archive &ar) const
236{
237 ar &V_NAME(ar, "type", m_type);
238 ar &V_NAME(ar, "size", size_type(m_size));
239 ar &V_NAME(ar, "exact", m_exact);
240 //std::cerr << "saving array: exact=" << m_exact << ", size=" << m_size << std::endl;
241 if (m_size > 0) {
242 if (m_dim[0] * m_dim[1] * m_dim[2] == m_size)
243 ar &V_NAME(ar, "elements", detail::wrap_array<Archive>(&m_data[0], m_exact, m_dim[0], m_dim[1], m_dim[2]));
244 else
245 ar &V_NAME(ar, "elements", detail::wrap_array<Archive>(&m_data[0], m_exact, m_size));
246 }
247}
248
249template<typename T, class allocator>
250template<class Archive>
251void shm_array<T, allocator>::load(Archive &ar)
252{
253 uint32_t type = 0;
254 ar &V_NAME(ar, "type", type);
255 assert(m_type == type);
256 size_type size = 0;
257 ar &V_NAME(ar, "size", size);
258 resize(size);
259 ar &V_NAME(ar, "exact", m_exact);
260 if (m_size > 0) {
261 if (m_dim[0] * m_dim[1] * m_dim[2] == m_size)
262 ar &V_NAME(ar, "elements", detail::wrap_array<Archive>(&m_data[0], m_exact, m_dim[0], m_dim[1], m_dim[2]));
263 else
264 ar &V_NAME(ar, "elements", detail::wrap_array<Archive>(&m_data[0], m_exact, m_size));
265 }
266}
267
268} // namespace vistle
269#endif
#define V_NAME(ar, name, obj)
Definition: archives_config.h:441
#define ARCHIVE_ACCESS_SPLIT
Definition: archives_config.h:502
Definition: allocator.h:12
Definition: shm_array.h:19
bool check() const
Definition: shm_array.h:66
void push_back(const T &v)
Definition: shm_array.h:108
T & at(const size_t idx)
Definition: shm_array.h:95
T & back()
Definition: shm_array.h:127
void setDimensionHint(const size_t sx, const size_t sy=1, const size_t sz=1)
Definition: shm_array.h:160
size_t capacity() const
Definition: shm_array.h:169
bool empty() const
Definition: shm_array.h:130
void reserve(const size_t new_capacity)
Definition: shm_array.h:170
T value_type
Definition: shm_array.h:21
shm_array(const size_t size, const allocator &alloc=allocator())
Definition: shm_array.h:33
const value_type & const_reference
Definition: shm_array.h:23
void shrink_to_fit()
Definition: shm_array.h:199
void resize(const size_t size, const T &value)
Definition: shm_array.h:145
T & operator[](const size_t idx) const
Definition: shm_array.h:94
void clear()
Definition: shm_array.h:131
T & front()
Definition: shm_array.h:128
void clearDimensionHint()
Definition: shm_array.h:155
shm_array(const allocator &alloc=allocator())
Definition: shm_array.h:27
size_t size() const
Definition: shm_array.h:133
void resize(const size_t size)
Definition: shm_array.h:134
allocator::pointer pointer
Definition: shm_array.h:85
static int typeId()
Definition: shm_impl.h:24
shm_array(const size_t size, const T &value, const allocator &alloc=allocator())
Definition: shm_array.h:39
int type() const
Definition: shm_array.h:65
T * data() const
Definition: shm_array.h:91
uint64_t size_type
Definition: shm_array.h:22
void emplace_back(Args &&...args)
Definition: shm_array.h:118
shm_array(shm_array &&other)
Definition: shm_array.h:45
void reserve_or_shrink(const size_t capacity)
Definition: shm_array.h:175
T * iterator
Definition: shm_array.h:86
iterator end() const
Definition: shm_array.h:90
T & at(const size_t idx) const
Definition: shm_array.h:101
const T * const_iterator
Definition: shm_array.h:87
~shm_array()
Definition: shm_array.h:59
T & operator[](const size_t idx)
Definition: shm_array.h:93
void setExact(bool exact)
Definition: shm_array.h:167
iterator begin() const
Definition: shm_array.h:89
Definition: allobjects.cpp:30
default_init_allocator< T > allocator
Definition: allocator.h:36
Definition: shmdata.h:12
@ ARRAY
Definition: shmdata.h:16
int refcount() const
Definition: shmdata.h:35