File indexing completed on 2025-01-18 10:13:55
0001
0002
0003
0004 #ifndef VECGEOM_BASE_SOA3D_H_
0005 #define VECGEOM_BASE_SOA3D_H_
0006
0007 #include "VecGeom/base/Cuda.h"
0008 #include "VecGeom/base/Global.h"
0009
0010 #include "VecGeom/base/Container3D.h"
0011 #include "VecGeom/backend/scalar/Backend.h"
0012 #ifdef VECGEOM_CUDA_INTERFACE
0013 #include "VecGeom/backend/cuda/Interface.h"
0014 #endif
0015
0016 #include <fstream>
0017
0018 namespace vecgeom {
0019
0020 VECGEOM_DEVICE_FORWARD_DECLARE(template <typename Type> class SOA3D;);
0021
0022 inline namespace VECGEOM_IMPL_NAMESPACE {
0023
0024
0025
0026
0027 #if __GNUC__ < 3 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 8)
0028
0029 #pragma GCC diagnostic push
0030 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
0031 #pragma GCC diagnostic ignored "-Weffc++"
0032 #define GCC_DIAG_POP_NEEDED
0033 #endif
0034
0035 template <typename T>
0036 class SOA3D : Container3D<SOA3D<T>> {
0037
0038 private:
0039 bool fAllocated = false;
0040 size_t fSize = 0, fCapacity = 0;
0041 T *fX = nullptr, *fY = nullptr, *fZ = nullptr;
0042
0043 public:
0044 typedef T value_type;
0045
0046 VECCORE_ATT_HOST_DEVICE
0047 SOA3D(T *x, T *y, T *z, size_t size);
0048
0049 VECCORE_ATT_HOST_DEVICE
0050 SOA3D(size_t size);
0051
0052 SOA3D(SOA3D<T> const &other);
0053
0054 SOA3D() = default;
0055
0056 VECCORE_ATT_HOST_DEVICE
0057 SOA3D &operator=(SOA3D<T> const &other);
0058
0059 VECCORE_ATT_HOST_DEVICE
0060 ~SOA3D();
0061
0062 VECCORE_ATT_HOST_DEVICE
0063 VECGEOM_FORCE_INLINE
0064 size_t size() const;
0065
0066 VECCORE_ATT_HOST_DEVICE
0067 VECGEOM_FORCE_INLINE
0068 size_t capacity() const;
0069
0070 VECCORE_ATT_HOST_DEVICE
0071 VECGEOM_FORCE_INLINE
0072 void resize(size_t newSize);
0073
0074 VECCORE_ATT_HOST_DEVICE
0075 VECGEOM_FORCE_INLINE
0076 void reserve(size_t newCapacity);
0077
0078 VECGEOM_FORCE_INLINE
0079 void clear();
0080
0081
0082
0083 VECCORE_ATT_HOST_DEVICE
0084 VECGEOM_FORCE_INLINE
0085 Vector3D<T> operator[](size_t index) const;
0086
0087 VECCORE_ATT_HOST_DEVICE
0088 VECGEOM_FORCE_INLINE
0089 T x(size_t index) const;
0090
0091 VECCORE_ATT_HOST_DEVICE
0092 VECGEOM_FORCE_INLINE
0093 T &x(size_t index);
0094
0095 VECCORE_ATT_HOST_DEVICE
0096 VECGEOM_FORCE_INLINE
0097 T *x();
0098
0099 VECCORE_ATT_HOST_DEVICE
0100 VECGEOM_FORCE_INLINE
0101 T const *x() const;
0102
0103 VECCORE_ATT_HOST_DEVICE
0104 VECGEOM_FORCE_INLINE
0105 T y(size_t index) const;
0106
0107 VECCORE_ATT_HOST_DEVICE
0108 VECGEOM_FORCE_INLINE
0109 T &y(size_t index);
0110
0111 VECCORE_ATT_HOST_DEVICE
0112 VECGEOM_FORCE_INLINE
0113 T *y();
0114
0115 VECCORE_ATT_HOST_DEVICE
0116 VECGEOM_FORCE_INLINE
0117 T const *y() const;
0118
0119 VECCORE_ATT_HOST_DEVICE
0120 VECGEOM_FORCE_INLINE
0121 T z(size_t index) const;
0122
0123 VECCORE_ATT_HOST_DEVICE
0124 VECGEOM_FORCE_INLINE
0125 T &z(size_t index);
0126
0127 VECCORE_ATT_HOST_DEVICE
0128 VECGEOM_FORCE_INLINE
0129 T *z();
0130
0131 VECCORE_ATT_HOST_DEVICE
0132 VECGEOM_FORCE_INLINE
0133 T const *z() const;
0134
0135
0136
0137 VECCORE_ATT_HOST_DEVICE
0138 VECGEOM_FORCE_INLINE
0139 void set(size_t index, T x, T y, T z);
0140
0141 VECCORE_ATT_HOST_DEVICE
0142 VECGEOM_FORCE_INLINE
0143 void set(size_t index, Vector3D<T> const &vec);
0144
0145 VECCORE_ATT_HOST_DEVICE
0146 VECGEOM_FORCE_INLINE
0147 void push_back(T x, T y, T z);
0148
0149 VECCORE_ATT_HOST_DEVICE
0150 VECGEOM_FORCE_INLINE
0151 void push_back(Vector3D<T> const &vec);
0152
0153 #ifdef VECGEOM_CUDA_INTERFACE
0154 DevicePtr<cuda::SOA3D<T>> CopyToGpu(DevicePtr<T> xGpu, DevicePtr<T> yGpu, DevicePtr<T> zGpu) const;
0155 DevicePtr<cuda::SOA3D<T>> CopyToGpu(DevicePtr<T> xGpu, DevicePtr<T> yGpu, DevicePtr<T> zGpu, size_t size) const;
0156 #endif
0157
0158 void ToFile(std::string ) const;
0159 int FromFile(std::string );
0160
0161 private:
0162 VECCORE_ATT_HOST_DEVICE
0163 void Allocate();
0164
0165 VECCORE_ATT_HOST_DEVICE
0166 void Deallocate();
0167 };
0168
0169 #if defined(GCC_DIAG_POP_NEEDED)
0170
0171 #pragma GCC diagnostic pop
0172 #undef GCC_DIAG_POP_NEEDED
0173
0174 #endif
0175
0176 template <typename T>
0177 VECCORE_ATT_HOST_DEVICE
0178 SOA3D<T>::SOA3D(T *xval, T *yval, T *zval, size_t sz)
0179 : fAllocated(false), fSize(sz), fCapacity(fSize), fX(xval), fY(yval), fZ(zval)
0180 {
0181 }
0182
0183 template <typename T>
0184 VECCORE_ATT_HOST_DEVICE
0185 SOA3D<T>::SOA3D(size_t sz) : fSize(sz), fCapacity(sz)
0186 {
0187 Allocate();
0188 }
0189
0190 template <typename T>
0191 SOA3D<T>::SOA3D(SOA3D<T> const &rhs)
0192 : fAllocated(false), fSize(rhs.fSize), fCapacity(rhs.fCapacity)
0193 {
0194 if (rhs.fAllocated) {
0195 Allocate();
0196 copy(rhs.fX, rhs.fX + rhs.fSize, fX);
0197 copy(rhs.fY, rhs.fY + rhs.fSize, fY);
0198 copy(rhs.fZ, rhs.fZ + rhs.fSize, fZ);
0199 } else {
0200 fX = rhs.fX;
0201 fY = rhs.fY;
0202 fZ = rhs.fZ;
0203 }
0204 }
0205
0206 template <typename T>
0207 VECCORE_ATT_HOST_DEVICE
0208 SOA3D<T> &SOA3D<T>::operator=(SOA3D<T> const &rhs)
0209 {
0210 #ifndef VECCORE_CUDA_DEVICE_COMPILATION
0211 fSize = rhs.fSize;
0212 fCapacity = rhs.fCapacity;
0213 Deallocate();
0214 if (rhs.fAllocated && rhs.fSize > 0) {
0215 Allocate();
0216 copy(rhs.fX, rhs.fX + rhs.fSize, fX);
0217 copy(rhs.fY, rhs.fY + rhs.fSize, fY);
0218 copy(rhs.fZ, rhs.fZ + rhs.fSize, fZ);
0219 } else {
0220 fX = rhs.fX;
0221 fY = rhs.fY;
0222 fZ = rhs.fZ;
0223 }
0224 #else
0225 fAllocated = false;
0226 fSize = rhs.fSize;
0227 fCapacity = rhs.fCapacity;
0228 fX = rhs.fX;
0229 fY = rhs.fY;
0230 fZ = rhs.fZ;
0231 #endif
0232 return *this;
0233 }
0234
0235 template <typename T>
0236 VECCORE_ATT_HOST_DEVICE
0237 SOA3D<T>::~SOA3D()
0238 {
0239 #ifndef VECCORE_CUDA_DEVICE_COMPILATION
0240 Deallocate();
0241 #endif
0242 }
0243
0244 template <typename T>
0245 VECCORE_ATT_HOST_DEVICE
0246 size_t SOA3D<T>::size() const
0247 {
0248 return fSize;
0249 }
0250
0251 template <typename T>
0252 VECCORE_ATT_HOST_DEVICE
0253 size_t SOA3D<T>::capacity() const
0254 {
0255 return fCapacity;
0256 }
0257
0258 template <typename T>
0259 VECCORE_ATT_HOST_DEVICE
0260 void SOA3D<T>::resize(size_t newSize)
0261 {
0262 assert(newSize <= fCapacity);
0263 fSize = newSize;
0264 }
0265
0266 template <typename T>
0267 VECCORE_ATT_HOST_DEVICE
0268 void SOA3D<T>::reserve(size_t newCapacity)
0269 {
0270 fCapacity = newCapacity;
0271 T *xNew, *yNew, *zNew;
0272 xNew = AlignedAllocate<T>(fCapacity);
0273 yNew = AlignedAllocate<T>(fCapacity);
0274 zNew = AlignedAllocate<T>(fCapacity);
0275 fSize = (fSize > fCapacity) ? fCapacity : fSize;
0276 if (fX && fY && fZ) {
0277 copy(fX, fX + fSize, xNew);
0278 copy(fY, fY + fSize, yNew);
0279 copy(fZ, fZ + fSize, zNew);
0280 }
0281 Deallocate();
0282 fX = xNew;
0283 fY = yNew;
0284 fZ = zNew;
0285 fAllocated = true;
0286 }
0287
0288 template <typename T>
0289 void SOA3D<T>::clear()
0290 {
0291 Deallocate();
0292 fSize = 0;
0293 fCapacity = 0;
0294 }
0295
0296 template <typename T>
0297 VECCORE_ATT_HOST_DEVICE
0298 void SOA3D<T>::Allocate()
0299 {
0300 if (fCapacity == 0) return;
0301
0302 fX = AlignedAllocate<T>(fCapacity);
0303 fY = AlignedAllocate<T>(fCapacity);
0304 fZ = AlignedAllocate<T>(fCapacity);
0305 fAllocated = true;
0306 }
0307
0308 template <typename T>
0309 VECCORE_ATT_HOST_DEVICE
0310 void SOA3D<T>::Deallocate()
0311 {
0312 if (fAllocated) {
0313 AlignedFree(fX);
0314 AlignedFree(fY);
0315 AlignedFree(fZ);
0316 }
0317 fAllocated = false;
0318 }
0319
0320 template <typename T>
0321 VECCORE_ATT_HOST_DEVICE
0322 Vector3D<T> SOA3D<T>::operator[](size_t index) const
0323 {
0324 return Vector3D<T>(fX[index], fY[index], fZ[index]);
0325 }
0326
0327 template <typename T>
0328 VECCORE_ATT_HOST_DEVICE
0329 T SOA3D<T>::x(size_t index) const
0330 {
0331 return fX[index];
0332 }
0333
0334 template <typename T>
0335 VECCORE_ATT_HOST_DEVICE
0336 T &SOA3D<T>::x(size_t index)
0337 {
0338 return fX[index];
0339 }
0340
0341 template <typename T>
0342 VECCORE_ATT_HOST_DEVICE
0343 T *SOA3D<T>::x()
0344 {
0345 return fX;
0346 }
0347
0348 template <typename T>
0349 VECCORE_ATT_HOST_DEVICE
0350 T const *SOA3D<T>::x() const
0351 {
0352 return fX;
0353 }
0354
0355 template <typename T>
0356 VECCORE_ATT_HOST_DEVICE
0357 T SOA3D<T>::y(size_t index) const
0358 {
0359 return fY[index];
0360 }
0361
0362 template <typename T>
0363 VECCORE_ATT_HOST_DEVICE
0364 T &SOA3D<T>::y(size_t index)
0365 {
0366 return fY[index];
0367 }
0368
0369 template <typename T>
0370 VECCORE_ATT_HOST_DEVICE
0371 T *SOA3D<T>::y()
0372 {
0373 return fY;
0374 }
0375
0376 template <typename T>
0377 VECCORE_ATT_HOST_DEVICE
0378 T const *SOA3D<T>::y() const
0379 {
0380 return fY;
0381 }
0382
0383 template <typename T>
0384 VECCORE_ATT_HOST_DEVICE
0385 T SOA3D<T>::z(size_t index) const
0386 {
0387 return fZ[index];
0388 }
0389
0390 template <typename T>
0391 VECCORE_ATT_HOST_DEVICE
0392 T &SOA3D<T>::z(size_t index)
0393 {
0394 return fZ[index];
0395 }
0396
0397 template <typename T>
0398 VECCORE_ATT_HOST_DEVICE
0399 T *SOA3D<T>::z()
0400 {
0401 return fZ;
0402 }
0403
0404 template <typename T>
0405 VECCORE_ATT_HOST_DEVICE
0406 T const *SOA3D<T>::z() const
0407 {
0408 return fZ;
0409 }
0410
0411 template <typename T>
0412 VECGEOM_FORCE_INLINE
0413 VECCORE_ATT_HOST_DEVICE
0414 void SOA3D<T>::set(size_t index, T xval, T yval, T zval)
0415 {
0416
0417
0418 #ifndef VECCORE_CUDA
0419 assert(index < fCapacity);
0420 #endif
0421 fX[index] = xval;
0422 fY[index] = yval;
0423 fZ[index] = zval;
0424 }
0425
0426 template <typename T>
0427 VECGEOM_FORCE_INLINE
0428 VECCORE_ATT_HOST_DEVICE
0429 void SOA3D<T>::set(size_t index, Vector3D<T> const &vec)
0430 {
0431
0432
0433 #ifndef VECCORE_CUDA
0434 assert(index < fCapacity);
0435 #endif
0436 fX[index] = vec[0];
0437 fY[index] = vec[1];
0438 fZ[index] = vec[2];
0439 }
0440
0441 template <typename T>
0442 VECCORE_ATT_HOST_DEVICE
0443 void SOA3D<T>::push_back(T xval, T yval, T zval)
0444 {
0445 fX[fSize] = xval;
0446 fY[fSize] = yval;
0447 fZ[fSize] = zval;
0448 ++fSize;
0449 }
0450
0451 template <typename T>
0452 VECCORE_ATT_HOST_DEVICE
0453 void SOA3D<T>::push_back(Vector3D<T> const &vec)
0454 {
0455 push_back(vec[0], vec[1], vec[2]);
0456 }
0457
0458 template <typename T>
0459 void SOA3D<T>::ToFile(std::string filename) const
0460 {
0461 std::ofstream outfile(filename, std::ios::binary);
0462 outfile.write(reinterpret_cast<const char *>(&fSize), sizeof(fSize));
0463 outfile.write(reinterpret_cast<const char *>(&fCapacity), sizeof(fCapacity));
0464 outfile.write(reinterpret_cast<char *>(fX), fCapacity * sizeof(T));
0465 outfile.write(reinterpret_cast<char *>(fY), fCapacity * sizeof(T));
0466 outfile.write(reinterpret_cast<char *>(fZ), fCapacity * sizeof(T));
0467 }
0468
0469
0470
0471 template <typename T>
0472 int SOA3D<T>::FromFile(std::string filename)
0473 {
0474
0475 decltype(fSize) s;
0476 decltype(fCapacity) cap;
0477 std::ifstream fin(filename, std::ios::binary);
0478 fin.read(reinterpret_cast<char *>(&s), sizeof(s));
0479 if (!fin) return -1;
0480 fin.read(reinterpret_cast<char *>(&cap), sizeof(cap));
0481 if (!fin) return -2;
0482
0483
0484
0485 fin.read(reinterpret_cast<char *>(fX), fCapacity * sizeof(T));
0486 if (!fin) return -3;
0487
0488 fin.read(reinterpret_cast<char *>(fY), fCapacity * sizeof(T));
0489 if (!fin) return -4;
0490
0491 fin.read(reinterpret_cast<char *>(fZ), fCapacity * sizeof(T));
0492 if (!fin) return -5;
0493
0494 return fCapacity;
0495 }
0496
0497 #ifdef VECGEOM_CUDA_INTERFACE
0498
0499 template <typename T>
0500 DevicePtr<cuda::SOA3D<T>> SOA3D<T>::CopyToGpu(DevicePtr<T> xGpu, DevicePtr<T> yGpu, DevicePtr<T> zGpu) const
0501 {
0502 xGpu.ToDevice(fX, fSize);
0503 yGpu.ToDevice(fY, fSize);
0504 zGpu.ToDevice(fZ, fSize);
0505
0506 DevicePtr<cuda::SOA3D<T>> gpu_ptr;
0507 gpu_ptr.Allocate();
0508 gpu_ptr.Construct(xGpu, yGpu, zGpu, fSize);
0509 }
0510
0511 template <typename T>
0512 DevicePtr<cuda::SOA3D<T>> SOA3D<T>::CopyToGpu(DevicePtr<T> xGpu, DevicePtr<T> yGpu, DevicePtr<T> zGpu,
0513 size_t count) const
0514 {
0515 xGpu.ToDevice(fX, count);
0516 yGpu.ToDevice(fY, count);
0517 zGpu.ToDevice(fZ, count);
0518
0519 DevicePtr<cuda::SOA3D<T>> gpu_ptr;
0520 gpu_ptr.Allocate();
0521 gpu_ptr.Construct(xGpu, yGpu, zGpu, fSize);
0522 }
0523
0524 #endif
0525 }
0526 }
0527
0528 #endif