File indexing completed on 2025-01-30 10:26:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef VOLUMES_UNPLACEDVOLUMEIMPLHELPER_H_
0011 #define VOLUMES_UNPLACEDVOLUMEIMPLHELPER_H_
0012
0013 #include "VecGeom/base/Global.h"
0014 #include "VecGeom/base/SOA3D.h"
0015 #include "VecGeom/volumes/UnplacedVolume.h"
0016 #include "VecGeom/management/VolumeFactory.h"
0017
0018 #ifndef __clang__
0019 #pragma GCC diagnostic push
0020
0021
0022
0023
0024 #pragma GCC diagnostic ignored "-Waggressive-loop-optimizations"
0025 #endif
0026
0027 namespace vecgeom {
0028
0029 VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_2t(class, CommonUnplacedVolumeImplHelper, typename, typename);
0030
0031 inline namespace VECGEOM_IMPL_NAMESPACE {
0032
0033
0034 template <class Implementation, typename Real_v>
0035 VECGEOM_FORCE_INLINE
0036 static void DistanceToOutLoop(typename Implementation::UnplacedStruct_t const *shapestruct, const size_t offset,
0037 const size_t size, SOA3D<Precision> const &points, SOA3D<Precision> const &directions,
0038 Precision const *step_max, Precision *output)
0039 {
0040 using vecCore::FromPtr;
0041 for (decltype(points.size()) i(offset); i < size; i += vecCore::VectorSize<Real_v>()) {
0042 Vector3D<Real_v> point(FromPtr<Real_v>(points.x() + i), FromPtr<Real_v>(points.y() + i),
0043 FromPtr<Real_v>(points.z() + i));
0044 Vector3D<Real_v> dir(FromPtr<Real_v>(directions.x() + i), FromPtr<Real_v>(directions.y() + i),
0045 FromPtr<Real_v>(directions.z() + i));
0046 Real_v stepMax_v = FromPtr<Real_v>(&step_max[i]);
0047 Real_v result;
0048 Implementation::template DistanceToOut<Real_v>(*shapestruct, point, dir, stepMax_v, result);
0049 vecCore::Store(result, &output[i]);
0050 }
0051 }
0052
0053 template <class Implementation, typename Real_v>
0054 VECGEOM_FORCE_INLINE
0055 static void SafetyToOutLoop(typename Implementation::UnplacedStruct_t const *shapestruct, const size_t offset,
0056 const size_t size, SOA3D<Precision> const &points, Precision *output)
0057 {
0058 using vecCore::FromPtr;
0059 const decltype(points.size()) len(size);
0060 for (decltype(points.size()) i(offset); i < len; i += vecCore::VectorSize<Real_v>()) {
0061 Vector3D<Real_v> point(FromPtr<Real_v>(points.x() + i), FromPtr<Real_v>(points.y() + i),
0062 FromPtr<Real_v>(points.z() + i));
0063 Real_v result(kInfLength);
0064 Implementation::template SafetyToOut<Real_v>(*shapestruct, point, result);
0065 vecCore::Store(result, &output[i]);
0066 }
0067 }
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 template <class Implementation, class BaseUnplVol = VUnplacedVolume>
0078 class CommonUnplacedVolumeImplHelper : public BaseUnplVol {
0079
0080 public:
0081 using UnplacedStruct_t = typename Implementation::UnplacedStruct_t;
0082 using UnplacedVolume_t = typename Implementation::UnplacedVolume_t;
0083
0084
0085 using BaseUnplVol::BaseUnplVol;
0086
0087 using BaseUnplVol::DistanceToIn;
0088 using BaseUnplVol::DistanceToOut;
0089 using BaseUnplVol::SafetyToIn;
0090 using BaseUnplVol::SafetyToOut;
0091
0092 VECCORE_ATT_HOST_DEVICE
0093 VECGEOM_FORCE_INLINE
0094 virtual Precision DistanceToOut(Vector3D<Precision> const &p, Vector3D<Precision> const &d,
0095 Precision step_max = kInfLength) const override
0096 {
0097 #ifndef VECCORE_CUDA
0098 assert(d.IsNormalized() && " direction not normalized in call to DistanceToOut ");
0099 #endif
0100 Precision output = kInfLength;
0101 Implementation::template DistanceToOut(((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct(), p, d, step_max,
0102 output);
0103
0104
0105 #ifndef VECCORE_CUDA
0106 assert(!((output < 0.) && std::isinf((Precision)output)));
0107 #endif
0108 return output;
0109 }
0110
0111
0112 VECCORE_ATT_HOST_DEVICE
0113 VECGEOM_FORCE_INLINE
0114 virtual Precision DistanceToOut(Vector3D<Precision> const &p, Vector3D<Precision> const &d,
0115 Vector3D<Precision> &normal, bool &convex,
0116 Precision step_max = kInfLength) const override
0117 {
0118 (void)p;
0119 (void)d;
0120 (void)normal;
0121 (void)convex;
0122 (void)step_max;
0123 assert(false);
0124 return 0.;
0125 }
0126
0127 VECCORE_ATT_HOST_DEVICE
0128 VECGEOM_FORCE_INLINE
0129 virtual bool Contains(Vector3D<Precision> const &p) const override
0130 {
0131 bool output(false);
0132 Implementation::Contains(((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct(), p, output);
0133 return output;
0134 }
0135
0136 VECCORE_ATT_HOST_DEVICE
0137 VECGEOM_FORCE_INLINE
0138 virtual EnumInside Inside(Vector3D<Precision> const &p) const override
0139 {
0140 Inside_t output(0);
0141 Implementation::Inside(((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct(), p, output);
0142 return (EnumInside)output;
0143 }
0144
0145 VECCORE_ATT_HOST_DEVICE
0146 virtual Precision DistanceToIn(Vector3D<Precision> const &p, Vector3D<Precision> const &d,
0147 const Precision step_max = kInfLength) const override
0148 {
0149 #ifndef VECCORE_CUDA
0150 assert(d.IsNormalized() && " direction not normalized in call to DistanceToOut ");
0151 #endif
0152 Precision output(kInfLength);
0153 Implementation::DistanceToIn(((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct(), p, d, step_max, output);
0154 return output;
0155 }
0156
0157 VECCORE_ATT_HOST_DEVICE
0158 virtual Precision SafetyToOut(Vector3D<Precision> const &p) const override
0159 {
0160 Precision output(kInfLength);
0161 Implementation::SafetyToOut(((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct(), p, output);
0162 return output;
0163 }
0164
0165 VECCORE_ATT_HOST_DEVICE
0166 virtual Precision SafetyToIn(Vector3D<Precision> const &p) const override
0167 {
0168 Precision output(kInfLength);
0169 Implementation::SafetyToIn(((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct(), p, output);
0170 return output;
0171 }
0172
0173 virtual int MemorySize() const override { return sizeof(*this); }
0174 };
0175
0176
0177
0178
0179 template <class Implementation, class BaseUnplVol = VUnplacedVolume>
0180 class SIMDUnplacedVolumeImplHelper : public CommonUnplacedVolumeImplHelper<Implementation, BaseUnplVol> {
0181 public:
0182 using Real_v = vecgeom::VectorBackend::Real_v;
0183 using UnplacedVolume_t = typename Implementation::UnplacedVolume_t;
0184 using Common_t = CommonUnplacedVolumeImplHelper<Implementation, BaseUnplVol>;
0185
0186 static constexpr bool SIMDHELPER = true;
0187
0188 using Common_t::Common_t;
0189
0190
0191 VECCORE_ATT_HOST_DEVICE
0192 virtual Real_v DistanceToOutVec(Vector3D<Real_v> const &p, Vector3D<Real_v> const &d,
0193 Real_v const &step_max) const override
0194 {
0195 Real_v output;
0196 Implementation::template DistanceToOut<Real_v>(((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct(), p, d,
0197 step_max, output);
0198 return output;
0199 }
0200
0201
0202 VECCORE_ATT_HOST_DEVICE
0203 virtual Real_v DistanceToInVec(Vector3D<Real_v> const &p, Vector3D<Real_v> const &d,
0204 Real_v const &step_max) const override
0205 {
0206 Real_v output(kInfLength);
0207 Implementation::template DistanceToIn<Real_v>(((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct(), p, d,
0208 step_max, output);
0209 return output;
0210 }
0211
0212
0213 VECCORE_ATT_HOST_DEVICE
0214 virtual Real_v SafetyToOutVec(Vector3D<Real_v> const &p) const override
0215 {
0216 Real_v output(kInfLength);
0217 Implementation::template SafetyToOut<Real_v>(((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct(), p, output);
0218 return output;
0219 }
0220
0221
0222 VECCORE_ATT_HOST_DEVICE
0223 virtual Real_v SafetyToInVec(Vector3D<Real_v> const &p) const override
0224 {
0225 Real_v output(kInfLength);
0226 Implementation::template SafetyToIn<Real_v>(((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct(), p, output);
0227 return output;
0228 }
0229
0230 using UnplacedStruct_t = typename Implementation::UnplacedStruct_t;
0231 using Common_t::DistanceToOut;
0232 using Common_t::SafetyToOut;
0233
0234 virtual void DistanceToOut(SOA3D<Precision> const &points, SOA3D<Precision> const &directions,
0235 Precision const *const step_max, Precision *const output) const override
0236 {
0237 auto offset = points.size() - points.size() % vecCore::VectorSize<VectorBackend::Real_v>();
0238 auto &shape = ((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct();
0239
0240 DistanceToOutLoop<Implementation, VectorBackend::Real_v>(&shape, 0, offset, points, directions, step_max, output);
0241
0242 DistanceToOutLoop<Implementation, ScalarBackend::Real_v>(&shape, offset, points.size(), points, directions,
0243 step_max, output);
0244 }
0245
0246 virtual void SafetyToOut(SOA3D<Precision> const &points, Precision *const output) const override
0247 {
0248 auto offset = points.size() - points.size() % vecCore::VectorSize<VectorBackend::Real_v>();
0249 auto &shape = ((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct();
0250
0251 SafetyToOutLoop<Implementation, VectorBackend::Real_v>(&shape, 0, offset, points, output);
0252
0253 SafetyToOutLoop<Implementation, ScalarBackend::Real_v>(&shape, offset, points.size(), points, output);
0254 }
0255 };
0256
0257
0258
0259
0260
0261 template <class Implementation, class BaseUnplVol = VUnplacedVolume>
0262 class LoopUnplacedVolumeImplHelper : public CommonUnplacedVolumeImplHelper<Implementation, BaseUnplVol> {
0263 public:
0264 using Real_v = vecgeom::VectorBackend::Real_v;
0265 using Real_s = vecgeom::ScalarBackend::Real_v;
0266 using UnplacedVolume_t = typename Implementation::UnplacedVolume_t;
0267 using Common_t = CommonUnplacedVolumeImplHelper<Implementation, BaseUnplVol>;
0268
0269 static constexpr bool SIMDHELPER = false;
0270
0271
0272 using Common_t::Common_t;
0273 using Common_t::DistanceToIn;
0274 using Common_t::DistanceToOut;
0275 using Common_t::SafetyToIn;
0276 using Common_t::SafetyToOut;
0277
0278
0279 VECCORE_ATT_HOST_DEVICE
0280 virtual Real_v DistanceToOutVec(Vector3D<Real_v> const &p, Vector3D<Real_v> const &d,
0281 Real_v const &step_max) const override
0282 {
0283
0284 Real_v output(kInfLength);
0285 using vecCore::LaneAt;
0286 for (size_t i = 0; i < vecCore::VectorSize<Real_v>(); ++i) {
0287 Vector3D<Real_s> ps(LaneAt(p.x(), i), LaneAt(p.y(), i), LaneAt(p.z(), i));
0288 Vector3D<Real_s> ds(LaneAt(d.x(), i), LaneAt(d.y(), i), LaneAt(d.z(), i));
0289 Real_s result;
0290 Implementation::template DistanceToOut<Real_s>(((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct(), ps, ds,
0291 LaneAt(step_max, i), result);
0292 vecCore::AssignLane(output, i, result);
0293 }
0294 return output;
0295 }
0296
0297
0298 VECCORE_ATT_HOST_DEVICE
0299 virtual Real_v DistanceToInVec(Vector3D<Real_v> const &p, Vector3D<Real_v> const &d,
0300 Real_v const &step_max) const override
0301 {
0302
0303 Real_v output(kInfLength);
0304 using vecCore::LaneAt;
0305 for (size_t i = 0; i < vecCore::VectorSize<Real_v>(); ++i) {
0306 Vector3D<Real_s> ps(LaneAt(p.x(), i), LaneAt(p.y(), i), LaneAt(p.z(), i));
0307 Vector3D<Real_s> ds(LaneAt(d.x(), i), LaneAt(d.y(), i), LaneAt(d.z(), i));
0308 Real_s tmp(-1.);
0309 Implementation::template DistanceToIn<Real_s>(((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct(), ps, ds,
0310 LaneAt(step_max, i), tmp);
0311 vecCore::AssignLane(output, i, tmp);
0312 }
0313 return output;
0314 }
0315
0316
0317 VECCORE_ATT_HOST_DEVICE
0318 virtual Real_v SafetyToOutVec(Vector3D<Real_v> const &p) const override
0319 {
0320
0321 Real_v output(-1.);
0322 using vecCore::LaneAt;
0323 for (size_t i = 0; i < vecCore::VectorSize<Real_v>(); ++i) {
0324 Vector3D<Real_s> ps(LaneAt(p.x(), i), LaneAt(p.y(), i), LaneAt(p.z(), i));
0325 Real_s tmp(kInfLength);
0326 Implementation::template SafetyToOut<Real_s>(((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct(), ps, tmp);
0327 vecCore::AssignLane(output, i, tmp);
0328 }
0329 return output;
0330 }
0331
0332
0333 VECCORE_ATT_HOST_DEVICE
0334 virtual Real_v SafetyToInVec(Vector3D<Real_v> const &p) const override
0335 {
0336
0337 Real_v output(kInfLength);
0338 using vecCore::LaneAt;
0339 for (size_t i = 0; i < vecCore::VectorSize<Real_v>(); ++i) {
0340 Vector3D<Real_s> ps(LaneAt(p.x(), i), LaneAt(p.y(), i), LaneAt(p.z(), i));
0341 Real_s tmp;
0342 Implementation::template SafetyToIn<Real_s>(((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct(), ps, tmp);
0343 vecCore::AssignLane(output, i, tmp);
0344 }
0345 return output;
0346 }
0347
0348 using UnplacedStruct_t = typename Implementation::UnplacedStruct_t;
0349
0350 virtual void DistanceToOut(SOA3D<Precision> const &points, SOA3D<Precision> const &directions,
0351 Precision const *const step_max, Precision *const output) const override
0352 {
0353 auto &shape = ((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct();
0354 DistanceToOutLoop<Implementation, Precision>(&shape, 0, points.size(), points, directions, step_max, output);
0355 }
0356
0357 virtual void SafetyToOut(SOA3D<Precision> const &points, Precision *const output) const override
0358 {
0359 auto &shape = ((UnplacedVolume_t *)this)->UnplacedVolume_t::GetStruct();
0360 SafetyToOutLoop<Implementation, Precision>(&shape, 0, points.size(), points, output);
0361 }
0362 };
0363 }
0364 }
0365
0366 #ifndef __clang__
0367 #pragma GCC diagnostic pop
0368 #endif
0369
0370 #endif