Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-18 09:33:05

0001 #pragma once
0002 
0003 #include "VecGeom/base/Cuda.h"
0004 #include "VecGeom/base/Global.h"
0005 #include "VecGeom/base/SOA3D.h"
0006 
0007 #include <algorithm>
0008 #include "VecGeom/base/Assert.h"
0009 
0010 #ifdef VECGEOM_DISTANCE_DEBUG
0011 #include "VecGeom/volumes/utilities/ResultComparator.h"
0012 #endif
0013 
0014 namespace vecgeom {
0015 
0016 // putting a forward declaration by hand
0017 VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE(class, SpecializedVolImplHelper, typename);
0018 // VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1t_2v(class, SpecializedVolImplHelper, typename, TranslationCode,
0019 //                                            translation::kGeneric, RotationCode, rotation::kGeneric);
0020 
0021 inline namespace VECGEOM_IMPL_NAMESPACE {
0022 
0023 template <class Specialization>
0024 class SpecializedVolImplHelper : public Specialization::PlacedShape_t {
0025 
0026   using PlacedShape_t    = typename Specialization::PlacedShape_t;
0027   using UnplacedVolume_t = typename Specialization::UnplacedVolume_t;
0028 
0029 public:
0030 #ifndef VECCORE_CUDA
0031   SpecializedVolImplHelper(VPlacedVolume const *other)
0032       : PlacedShape_t(other->GetName(), other->GetLogicalVolume(), other->GetTransformation())
0033   {
0034   }
0035 
0036   SpecializedVolImplHelper(char const *const label, LogicalVolume const *const logical_volume,
0037                            Transformation3D const *const transformation)
0038       : PlacedShape_t(label, logical_volume, transformation)
0039   {
0040   }
0041 
0042   SpecializedVolImplHelper(char const *const label, LogicalVolume *const logical_volume,
0043                            Transformation3D const *const transformation)
0044       : PlacedShape_t(label, logical_volume, transformation)
0045   {
0046   }
0047 
0048   SpecializedVolImplHelper(LogicalVolume const *const logical_volume, Transformation3D const *const transformation)
0049       : SpecializedVolImplHelper("", logical_volume, transformation)
0050   {
0051   }
0052 
0053   // this constructor mimics the constructor from the Unplaced solid
0054   // it ensures that placed volumes can be constructed just like ordinary Geant4/ROOT solids
0055   template <typename... ArgTypes>
0056   SpecializedVolImplHelper(char const *const label, ArgTypes... params)
0057       : SpecializedVolImplHelper(label, new LogicalVolume(new UnplacedVolume_t(params...)),
0058                                  &Transformation3D::kIdentity)
0059   {
0060   }
0061 
0062 #else // Compiling for CUDA
0063   VECCORE_ATT_DEVICE SpecializedVolImplHelper(LogicalVolume const *const logical_volume,
0064                                               Transformation3D const *const transformation, const unsigned int id,
0065                                               const int copy_no, const int child_id)
0066       : PlacedShape_t(logical_volume, transformation, id, copy_no, child_id)
0067   {
0068   }
0069 #endif
0070   using PlacedShape_t::Contains;
0071   using PlacedShape_t::DistanceToIn;
0072   using PlacedShape_t::DistanceToOut;
0073   using PlacedShape_t::Inside;
0074   using PlacedShape_t::PlacedShape_t;
0075   using PlacedShape_t::SafetyToIn;
0076   using PlacedShape_t::SafetyToOut;
0077   using PlacedShape_t::UnplacedContains;
0078 
0079   virtual int MemorySize() const override { return sizeof(*this); }
0080 
0081   VECCORE_ATT_HOST_DEVICE
0082   virtual EnumInside Inside(Vector3D<Precision> const &point) const override
0083   {
0084     Inside_t output;
0085     Transformation3D const *tr = this->GetTransformation();
0086     Specialization::Inside(*this->GetUnplacedStruct(), tr->Transform<Precision>(point), output);
0087     return (EnumInside)output;
0088   }
0089 
0090   VECCORE_ATT_HOST_DEVICE
0091   virtual bool Contains(Vector3D<Precision> const &point) const override
0092   {
0093     bool output(false);
0094     Transformation3D const *tr = this->GetTransformation();
0095     Vector3D<Precision> lp     = tr->Transform<Precision>(point);
0096     Specialization::Contains(*this->GetUnplacedStruct(), lp, output);
0097     return output;
0098   }
0099 
0100   VECCORE_ATT_HOST_DEVICE
0101   virtual bool Contains(Vector3D<Precision> const &point, Vector3D<Precision> &localPoint) const override
0102   {
0103     bool output(false);
0104     Transformation3D const *tr = this->GetTransformation();
0105     localPoint                 = tr->Transform<Precision>(point);
0106     Specialization::Contains(*this->GetUnplacedStruct(), localPoint, output);
0107 #ifdef VECGEOM_DISTANCE_DEBUG
0108     DistanceComparator::CompareUnplacedContains(this, output, localPoint);
0109 #endif
0110     return output;
0111   }
0112 
0113   VECCORE_ATT_HOST_DEVICE
0114   virtual Precision DistanceToIn(Vector3D<Precision> const &point, Vector3D<Precision> const &direction,
0115                                  const Precision stepMax = kInfLength) const override
0116   {
0117     VECGEOM_ASSERT(direction.IsNormalized() && " direction not normalized in call to DistanceToIn ");
0118     Precision output(kInfLength);
0119     Transformation3D const *tr = this->GetTransformation();
0120     Specialization::DistanceToIn(*this->GetUnplacedStruct(), tr->Transform(point), tr->TransformDirection(direction),
0121                                  stepMax, output);
0122 #ifdef VECGEOM_DISTANCE_DEBUG
0123     DistanceComparator::CompareDistanceToIn(this, output, point, direction, stepMax);
0124 #endif
0125     return output;
0126   }
0127 
0128   VECCORE_ATT_HOST_DEVICE
0129   virtual Precision PlacedDistanceToOut(Vector3D<Precision> const &point, Vector3D<Precision> const &direction,
0130                                         const Precision stepMax = kInfLength) const override
0131   {
0132     VECGEOM_ASSERT(direction.IsNormalized() && " direction not normalized in call to PlacedDistanceToOut ");
0133     Transformation3D const *tr = this->GetTransformation();
0134     Precision output(-1.);
0135     Specialization::template DistanceToOut<>(*this->GetUnplacedStruct(), tr->Transform(point),
0136                                              tr->TransformDirection(direction), stepMax, output);
0137 
0138 #ifdef VECGEOM_DISTANCE_DEBUG
0139     DistanceComparator::CompareDistanceToOut(this, output, this->GetTransformation()->Transform(point),
0140                                              this->GetTransformation()->TransformDirection(direction), stepMax);
0141 #endif
0142     return output;
0143   }
0144 
0145   VECCORE_ATT_HOST_DEVICE
0146   virtual Precision SafetyToIn(Vector3D<Precision> const &point) const override
0147   {
0148     Precision output(kInfLength);
0149     Transformation3D const *tr = this->GetTransformation();
0150     Specialization::SafetyToIn(*this->GetUnplacedStruct(), tr->Transform(point), output);
0151     return output;
0152   }
0153 
0154 #ifdef VECGEOM_CUDA_INTERFACE
0155   using ThisClass_t = SpecializedVolImplHelper<Specialization>;
0156   virtual size_t DeviceSizeOf() const override { return DevicePtr<CudaType_t<ThisClass_t>>::SizeOf(); }
0157 
0158   DevicePtr<cuda::VPlacedVolume> CopyToGpu(DevicePtr<cuda::LogicalVolume> const logical_volume,
0159                                            DevicePtr<cuda::Transformation3D> const transform,
0160                                            DevicePtr<cuda::VPlacedVolume> const in_gpu_ptr) const override
0161   {
0162     DevicePtr<CudaType_t<ThisClass_t>> gpu_ptr(in_gpu_ptr);
0163     gpu_ptr.Construct(logical_volume, transform, this->id(), this->GetCopyNo(), this->GetChildId());
0164     VECGEOM_DEVICE_API_CALL(GetLastError());
0165     // Need to go via the void* because the regular c++ compilation
0166     // does not actually see the declaration for the cuda version
0167     // (and thus can not determine the inheritance).
0168     return DevicePtr<cuda::VPlacedVolume>((void *)gpu_ptr);
0169   }
0170 
0171   DevicePtr<cuda::VPlacedVolume> CopyToGpu(DevicePtr<cuda::LogicalVolume> const logical_volume,
0172                                            DevicePtr<cuda::Transformation3D> const transform) const override
0173   {
0174     DevicePtr<CudaType_t<ThisClass_t>> gpu_ptr;
0175     gpu_ptr.Allocate();
0176     return CopyToGpu(logical_volume, transform, DevicePtr<cuda::VPlacedVolume>((void *)gpu_ptr));
0177   }
0178 
0179   /**
0180    * Copy many instances of this class to the GPU.
0181    * \param host_volumes Host volumes to be copied. These should all be of the same type as the class that this function is called with.
0182    * \param logical_volumes GPU addresses of the logical volumes corresponding to the placed volumes.
0183    * \param transforms GPU addresses of the transformations corresponding to the placed volumes.
0184    * \param in_gpu_ptrs GPU addresses where the GPU instances of the host volumes should be placed.
0185    * \note This requires an explicit template instantiation of ConstructManyOnGpu<ThisClass_t>().
0186    * \see VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL and its multi-argument versions.
0187    */
0188   void CopyManyToGpu(std::vector<VPlacedVolume const *> const &host_volumes,
0189                      std::vector<DevicePtr<cuda::LogicalVolume>> const &logical_volumes,
0190                      std::vector<DevicePtr<cuda::Transformation3D>> const &transforms,
0191                      std::vector<DevicePtr<cuda::VPlacedVolume>> const &in_gpu_ptrs) const override
0192   {
0193     VECGEOM_ASSERT(host_volumes.size() == logical_volumes.size());
0194     VECGEOM_ASSERT(host_volumes.size() == transforms.size());
0195     VECGEOM_ASSERT(host_volumes.size() == in_gpu_ptrs.size());
0196 
0197     std::vector<decltype(std::declval<ThisClass_t>().id())> ids;
0198     std::vector<decltype(std::declval<ThisClass_t>().GetCopyNo())> copyNos;
0199     std::vector<decltype(std::declval<ThisClass_t>().GetChildId())> childIds;
0200     for (auto placedVol : host_volumes) {
0201       ids.push_back(placedVol->id());
0202       copyNos.push_back(placedVol->GetCopyNo());
0203       childIds.push_back(placedVol->GetChildId());
0204     }
0205 
0206     ConstructManyOnGpu<CudaType_t<ThisClass_t>>(in_gpu_ptrs.size(), in_gpu_ptrs.data(), logical_volumes.data(),
0207                                                 transforms.data(), ids.data(), copyNos.data(), childIds.data());
0208   }
0209 
0210 #endif // VECGEOM_CUDA_INTERFACE
0211 
0212 }; // End class SpecializedVolImplHelper
0213 
0214 } // namespace VECGEOM_IMPL_NAMESPACE
0215 } // namespace vecgeom