File indexing completed on 2025-03-13 09:29:12
0001
0002
0003
0004 #ifndef VECGEOM_BASE_VECTOR_H_
0005 #define VECGEOM_BASE_VECTOR_H_
0006
0007 #include "VecGeom/base/Config.h"
0008 #include "VecGeom/base/Cuda.h"
0009 #include "VecGeom/base/Global.h"
0010 #include <initializer_list>
0011 #ifdef VECGEOM_ENABLE_CUDA
0012 #include "VecGeom/backend/cuda/Interface.h"
0013 #endif
0014
0015 namespace vecgeom {
0016
0017 VECGEOM_DEVICE_FORWARD_DECLARE(template <typename Type> class Vector;);
0018 VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE(class, Vector, typename);
0019
0020 inline namespace VECGEOM_IMPL_NAMESPACE {
0021
0022 namespace Internal {
0023 template <typename T>
0024 struct AllocTrait {
0025
0026
0027 VECCORE_ATT_HOST_DEVICE
0028 static T *Allocate(size_t nElems) { return reinterpret_cast<T *>(new char[nElems * sizeof(T)]); }
0029
0030
0031 VECCORE_ATT_HOST_DEVICE
0032 static void Deallocate(T *startBuffer) { delete[]((char *)startBuffer); }
0033
0034 VECCORE_ATT_HOST_DEVICE
0035 static void Destroy(T &obj) { obj.~T(); };
0036
0037 VECCORE_ATT_HOST_DEVICE
0038 static void Destroy(T *arr, size_t nElem)
0039 {
0040 for (size_t i = 0; i < nElem; ++i)
0041 Destroy(arr[i]);
0042 }
0043 };
0044
0045 template <typename T>
0046 struct AllocTrait<T *> {
0047
0048
0049 VECCORE_ATT_HOST_DEVICE
0050 static T **Allocate(size_t nElems) { return reinterpret_cast<T **>(new char[nElems * sizeof(T *)]); }
0051
0052
0053 VECCORE_ATT_HOST_DEVICE
0054 static void Deallocate(T **startBuffer) { delete[]((char *)startBuffer); }
0055
0056 VECCORE_ATT_HOST_DEVICE
0057 static void Destroy(T *&) {}
0058
0059 VECCORE_ATT_HOST_DEVICE
0060 static void Destroy(T ** , size_t ) {}
0061 };
0062 }
0063
0064 template <typename Type>
0065 class VectorBase {
0066
0067 private:
0068 Type *fData;
0069 size_t fSize, fMemorySize;
0070 bool fAllocated;
0071
0072 public:
0073 using value_type = Type;
0074
0075 VECCORE_ATT_HOST_DEVICE
0076 VectorBase() : VectorBase(5) {}
0077
0078 VECCORE_ATT_HOST_DEVICE
0079 VectorBase(size_t maxsize) : fData(nullptr), fSize(0), fMemorySize(0), fAllocated(true) { reserve(maxsize); }
0080
0081 VECCORE_ATT_HOST_DEVICE
0082 VectorBase(Type *const vec, const int sz) : fData(vec), fSize(sz), fMemorySize(sz), fAllocated(false) {}
0083
0084 VECCORE_ATT_HOST_DEVICE
0085 VectorBase(Type *const vec, const int sz, const int maxsize)
0086 : fData(vec), fSize(sz), fMemorySize(maxsize), fAllocated(false)
0087 {
0088 }
0089
0090 VECCORE_ATT_HOST_DEVICE
0091 VectorBase(VectorBase const &other) : fSize(other.fSize), fMemorySize(other.fMemorySize), fAllocated(true)
0092 {
0093 fData = Internal::AllocTrait<Type>::Allocate(fMemorySize);
0094 for (size_t i = 0; i < fSize; ++i)
0095 new (&fData[i]) Type(other.fData[i]);
0096 }
0097
0098 VECCORE_ATT_HOST_DEVICE
0099 VectorBase &operator=(VectorBase const &other)
0100 {
0101 if (&other != this) {
0102 reserve(other.fMemorySize);
0103 for (size_t i = 0; i < other.fSize; ++i)
0104 push_back(other.fData[i]);
0105 }
0106 return *this;
0107 }
0108
0109 VECCORE_ATT_HOST_DEVICE
0110 VectorBase(std::initializer_list<Type> entries)
0111 {
0112 fSize = entries.size();
0113 fData = Internal::AllocTrait<Type>::Allocate(fSize);
0114 fAllocated = true;
0115 fMemorySize = entries.size() * sizeof(Type);
0116 for (auto itm : entries)
0117 this->push_back(itm);
0118 }
0119
0120 VECCORE_ATT_HOST_DEVICE
0121 ~VectorBase()
0122 {
0123 if (fAllocated) Internal::AllocTrait<Type>::Deallocate(fData);
0124 }
0125
0126 VECCORE_ATT_HOST_DEVICE
0127 void clear()
0128 {
0129 Internal::AllocTrait<Type>::Destroy(fData, fSize);
0130 fSize = 0;
0131 }
0132
0133 VECCORE_ATT_HOST_DEVICE
0134 VECGEOM_FORCE_INLINE
0135 Type &operator[](const int index) { return fData[index]; }
0136
0137 VECCORE_ATT_HOST_DEVICE
0138 VECGEOM_FORCE_INLINE
0139 Type const &operator[](const int index) const { return fData[index]; }
0140
0141 VECCORE_ATT_HOST_DEVICE
0142 void push_back(const Type item)
0143 {
0144 if (fSize == fMemorySize) {
0145 assert(fAllocated && "Trying to push on a 'fixed' size vector (memory "
0146 "not allocated by Vector itself)");
0147 reserve(fMemorySize << 1);
0148 }
0149 new (&fData[fSize]) Type(item);
0150 fSize++;
0151 }
0152
0153 typedef Type *iterator;
0154 typedef Type const *const_iterator;
0155
0156 VECCORE_ATT_HOST_DEVICE
0157 VECGEOM_FORCE_INLINE
0158 iterator begin() const { return &fData[0]; }
0159
0160 VECCORE_ATT_HOST_DEVICE
0161 VECGEOM_FORCE_INLINE
0162 iterator end() const { return &fData[fSize]; }
0163
0164 VECCORE_ATT_HOST_DEVICE
0165 VECGEOM_FORCE_INLINE
0166 const_iterator cbegin() const { return &fData[0]; }
0167
0168 VECCORE_ATT_HOST_DEVICE
0169 VECGEOM_FORCE_INLINE
0170 const_iterator cend() const { return &fData[fSize]; }
0171
0172 VECCORE_ATT_HOST_DEVICE
0173 VECGEOM_FORCE_INLINE
0174 size_t size() const { return fSize; }
0175
0176 VECCORE_ATT_HOST_DEVICE
0177 VECGEOM_FORCE_INLINE
0178 size_t capacity() const { return fMemorySize; }
0179
0180 VECCORE_ATT_HOST_DEVICE
0181 VECGEOM_FORCE_INLINE
0182 void resize(size_t newsize, Type value)
0183 {
0184 if (newsize <= fSize) {
0185 for (size_t i = newsize; i < fSize; ++i) {
0186 Internal::AllocTrait<Type>::Destroy(fData[i]);
0187 }
0188 fSize = newsize;
0189 } else {
0190 if (newsize > fMemorySize) {
0191 reserve(newsize);
0192 }
0193 for (size_t i = fSize; i < newsize; ++i)
0194 push_back(value);
0195 }
0196 }
0197
0198 VECCORE_ATT_HOST_DEVICE
0199 VECGEOM_FORCE_INLINE
0200 void reserve(size_t newsize)
0201 {
0202 if (newsize <= fMemorySize) {
0203
0204 } else {
0205 Type *newdata = Internal::AllocTrait<Type>::Allocate(newsize);
0206 for (size_t i = 0; i < fSize; ++i)
0207 new (&newdata[i]) Type(fData[i]);
0208 Internal::AllocTrait<Type>::Destroy(fData, fSize);
0209 if (fAllocated) {
0210 Internal::AllocTrait<Type>::Deallocate(fData);
0211 }
0212 fData = newdata;
0213 fMemorySize = newsize;
0214 fAllocated = true;
0215 }
0216 }
0217
0218 VECCORE_ATT_HOST_DEVICE
0219 VECGEOM_FORCE_INLINE
0220 iterator erase(const_iterator position)
0221 {
0222 iterator where = (begin() + (position - cbegin()));
0223 if (where + 1 != end()) {
0224 auto last = cend();
0225 for (auto c = where; (c + 1) != last; ++c)
0226 *c = *(c + 1);
0227 }
0228 --fSize;
0229 if (fSize) Internal::AllocTrait<Type>::Destroy(fData[fSize]);
0230 return where;
0231 }
0232 };
0233
0234 template <typename Type>
0235 class Vector : public VectorBase<Type> {
0236 public:
0237 using VectorBase<Type>::VectorBase;
0238 using typename VectorBase<Type>::iterator;
0239 using typename VectorBase<Type>::const_iterator;
0240
0241 #ifdef VECGEOM_CUDA_INTERFACE
0242 DevicePtr<cuda::Vector<CudaType_t<Type>>> CopyToGpu(DevicePtr<CudaType_t<Type>> const gpu_ptr_arr,
0243 DevicePtr<cuda::Vector<CudaType_t<Type>>> const gpu_ptr) const
0244 {
0245 gpu_ptr.Construct(gpu_ptr_arr, VectorBase<Type>::size());
0246 return gpu_ptr;
0247 }
0248 #endif
0249 };
0250 }
0251 }
0252
0253 #endif