00001
00025 #ifndef GALOIS_LARGEARRAY_H
00026 #define GALOIS_LARGEARRAY_H
00027
00028 #include "Galois/config.h"
00029 #include "Galois/gstl.h"
00030 #include "Galois/Runtime/ll/gio.h"
00031 #include "Galois/Runtime/mm/Mem.h"
00032
00033 #include <boost/utility.hpp>
00034 #include GALOIS_CXX11_STD_HEADER(utility)
00035
00036 namespace Galois {
00037
00044 template<typename T>
00045 class LargeArray: private boost::noncopyable {
00046 T* m_data;
00047 size_t m_size;
00048 int allocated;
00049
00050 public:
00051 typedef T raw_value_type;
00052 typedef T value_type;
00053 typedef size_t size_type;
00054 typedef ptrdiff_t difference_type;
00055 typedef value_type& reference;
00056 typedef const value_type& const_reference;
00057 typedef value_type* pointer;
00058 typedef const value_type* const_pointer;
00059 typedef pointer iterator;
00060 typedef const_pointer const_iterator;
00061 const static bool has_value = true;
00062
00063
00064 struct size_of {
00065 const static size_t value = sizeof(T);
00066 };
00067
00068 protected:
00069 void allocate(size_type n, bool interleave, bool prefault) {
00070 assert(!m_data);
00071 allocated = interleave ? 1 : 2;
00072 m_size = n;
00073 if (interleave)
00074 m_data = reinterpret_cast<T*>(Galois::Runtime::MM::largeInterleavedAlloc(sizeof(T) * n));
00075 else if (prefault)
00076 m_data = reinterpret_cast<T*>(Galois::Runtime::MM::largeAlloc(sizeof(T) * n, true));
00077 else
00078 m_data = reinterpret_cast<T*>(Galois::Runtime::MM::largeAlloc(sizeof(T) * n, false));
00079 }
00080
00081 public:
00085 LargeArray(void* d, size_t s): m_data(reinterpret_cast<T*>(d)), m_size(s), allocated(0) { }
00086
00087 LargeArray(): m_data(0), m_size(0), allocated(0) { }
00088
00089 ~LargeArray() {
00090 destroy();
00091 deallocate();
00092 }
00093
00094 const_reference at(difference_type x) const { return m_data[x]; }
00095 reference at(difference_type x) { return m_data[x]; }
00096 const_reference operator[](size_type x) const { return m_data[x]; }
00097 reference operator[](size_type x) { return m_data[x]; }
00098 void set(difference_type x, const_reference v) { m_data[x] = v; }
00099 size_type size() const { return m_size; }
00100 iterator begin() { return m_data; }
00101 const_iterator begin() const { return m_data; }
00102 iterator end() { return m_data + m_size; }
00103 const_iterator end() const { return m_data + m_size; }
00104
00106 void allocateInterleaved(size_type n) { allocate(n, true, true); }
00107
00116 void allocateLocal(size_type n, bool prefault = true) { allocate(n, false, prefault); }
00117
00118 template<typename... Args>
00119 void construct(Args&&... args) {
00120 for (T* ii = m_data, *ei = m_data + m_size; ii != ei; ++ii)
00121 new (ii) T(std::forward<Args>(args)...);
00122 }
00123
00124 template<typename... Args>
00125 void constructAt(size_type n, Args&&... args) {
00126 new (&m_data[n]) T(std::forward<Args>(args)...);
00127 }
00128
00130 template<typename... Args>
00131 void create(size_type n, Args&&... args) {
00132 allocateInterleaved(n);
00133 construct(std::forward<Args>(args)...);
00134 }
00135
00136 void deallocate() {
00137 if (!allocated) return;
00138 if (allocated == 1)
00139 Galois::Runtime::MM::largeInterleavedFree(m_data, sizeof(T) * m_size);
00140 else if (allocated == 2)
00141 Galois::Runtime::MM::largeFree(m_data, sizeof(T) * m_size);
00142 else
00143 GALOIS_DIE("Unknown allocation type");
00144 m_data = 0;
00145 m_size = 0;
00146 }
00147
00148 void destroy() {
00149 if (!allocated) return;
00150 if (!m_data) return;
00151 uninitialized_destroy(m_data, m_data + m_size);
00152 }
00153
00154 void destroyAt(size_type n) {
00155 assert(allocated);
00156 (&m_data[n])->~T();
00157 }
00158
00159
00160 const_pointer data() const { return m_data; }
00161 pointer data() { return m_data; }
00162 };
00163
00165 template<>
00166 class LargeArray<void>: private boost::noncopyable {
00167 public:
00168 LargeArray(void* d, size_t s) { }
00169 LargeArray() { }
00170
00171 typedef void raw_value_type;
00172 typedef void* value_type;
00173 typedef size_t size_type;
00174 typedef ptrdiff_t difference_type;
00175 typedef value_type reference;
00176 typedef const value_type const_reference;
00177 typedef value_type* pointer;
00178 typedef const value_type* const_pointer;
00179 typedef pointer iterator;
00180 typedef const_pointer const_iterator;
00181 const static bool has_value = false;
00182 struct size_of {
00183 const static size_t value = 0;
00184 };
00185
00186 const_reference at(difference_type x) const { return 0; }
00187 reference at(difference_type x) { return 0; }
00188 const_reference operator[](size_type x) const { return 0; }
00189 void set(difference_type x, const_reference v) { }
00190 size_type size() const { return 0; }
00191 iterator begin() { return 0; }
00192 const_iterator begin() const { return 0; }
00193 iterator end() { return 0; }
00194 const_iterator end() const { return 0; }
00195
00196 void allocateInterleaved(size_type n) { }
00197 void allocateLocal(size_type n, bool prefault = true) { }
00198 template<typename... Args> void construct(Args&&... args) { }
00199 template<typename... Args> void constructAt(size_type n, Args&&... args) { }
00200 template<typename... Args> void create(size_type n, Args&&... args) { }
00201
00202 void deallocate() { }
00203 void destroy() { }
00204 void destroyAt(size_type n) { }
00205
00206 const_pointer data() const { return 0; }
00207 pointer data() { return 0; }
00208 };
00209
00210 }
00211 #endif
00212