Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:58

0001 /*
0002  * SimpleABBoxLevelLocator.h
0003  *
0004  *  Created on: Aug 27, 2015
0005  *      Author: swenzel
0006  */
0007 
0008 #ifndef NAVIGATION_SIMPLEABBOXLEVELLOCATOR_H_
0009 #define NAVIGATION_SIMPLEABBOXLEVELLOCATOR_H_
0010 
0011 #include "VecGeom/navigation/VLevelLocator.h"
0012 #include "VecGeom/volumes/LogicalVolume.h"
0013 #include "VecGeom/volumes/PlacedVolume.h"
0014 #include "VecGeom/management/ABBoxManager.h"
0015 #include "VecGeom/volumes/kernel/BoxImplementation.h"
0016 
0017 #include "VecGeom/navigation/SimpleLevelLocator.h"
0018 
0019 #include <exception>
0020 #include <stdexcept>
0021 
0022 namespace vecgeom {
0023 inline namespace VECGEOM_IMPL_NAMESPACE {
0024 
0025 // a LevelLocator using a flat list of bounding boxes
0026 template <bool IsAssemblyAware = false>
0027 class TSimpleABBoxLevelLocator : public VLevelLocator {
0028 
0029 private:
0030   ABBoxManager &fAccelerationStructure;
0031   TSimpleABBoxLevelLocator() : fAccelerationStructure(ABBoxManager::Instance()) {}
0032 
0033   // the actual implementation kernel
0034   // the template "ifs" should be optimized away
0035   // arguments are pointers to allow for nullptr
0036   template <bool ExclV, bool ModifyState>
0037   __attribute__((always_inline)) bool LevelLocateKernel(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0038                                                         Vector3D<Precision> const &localpoint, NavigationState *state,
0039                                                         VPlacedVolume const *&pvol,
0040                                                         Vector3D<Precision> &daughterlocalpoint) const
0041   {
0042     int size;
0043     ABBoxManager::ABBoxContainer_v alignedbboxes = fAccelerationStructure.GetABBoxes_v(lvol, size);
0044 
0045     auto daughters = lvol->GetDaughtersp();
0046     // here the loop is over groups of bounding boxes
0047     // it is basically linear but vectorizable search
0048     for (int boxgroupid = 0; boxgroupid < size; ++boxgroupid) {
0049       using Bool_v = vecCore::Mask_v<ABBoxManager::Float_v>;
0050       Bool_v inBox;
0051       ABBoxImplementation::ABBoxContainsKernel(alignedbboxes[2 * boxgroupid], alignedbboxes[2 * boxgroupid + 1],
0052                                                localpoint, inBox);
0053       if (!vecCore::MaskEmpty(inBox)) {
0054         constexpr auto kVS = vecCore::VectorSize<ABBoxManager::Float_v>();
0055         // TODO: could start directly at first 1 in inBox
0056         for (size_t ii = 0; ii < kVS; ++ii) {
0057           auto daughterid = boxgroupid * kVS + ii;
0058           if (daughterid < daughters->size() && vecCore::MaskLaneAt(inBox, ii)) {
0059 
0060             VPlacedVolume const *daughter = (*daughters)[daughterid];
0061             if (ExclV) {
0062               if (daughter == exclvol) continue;
0063             }
0064             // call final treatment of candidate
0065             if (CheckCandidateVol<IsAssemblyAware, ModifyState>(daughter, localpoint, state, pvol, daughterlocalpoint))
0066               return true;
0067           }
0068         }
0069       }
0070     }
0071     return false;
0072   }
0073 
0074   template <bool ExclV, bool ModifyState>
0075   __attribute__((always_inline)) bool LevelLocateKernelWithDirection(LogicalVolume const *lvol,
0076                                                                      VPlacedVolume const *exclvol,
0077                                                                      Vector3D<Precision> const &localpoint,
0078                                                                      Vector3D<Precision> const &localdir,
0079                                                                      NavigationState *state, VPlacedVolume const *&pvol,
0080                                                                      Vector3D<Precision> &daughterlocalpoint) const
0081   {
0082 
0083     int size;
0084     ABBoxManager::ABBoxContainer_v alignedbboxes = fAccelerationStructure.GetABBoxes_v(lvol, size);
0085 
0086     auto daughters = lvol->GetDaughtersp();
0087     // here the loop is over groups of bounding boxes
0088     // it is basically linear but vectorizable search
0089     for (int boxgroupid = 0; boxgroupid < size; ++boxgroupid) {
0090       using Bool_v = vecCore::Mask_v<ABBoxManager::Float_v>;
0091       Bool_v inBox;
0092       ABBoxImplementation::ABBoxContainsKernel(alignedbboxes[2 * boxgroupid], alignedbboxes[2 * boxgroupid + 1],
0093                                                localpoint, inBox);
0094       if (!vecCore::MaskEmpty(inBox)) {
0095         constexpr auto kVS = vecCore::VectorSize<ABBoxManager::Float_v>();
0096         // TODO: could start directly at first 1 in inBox
0097         for (size_t ii = 0; ii < kVS; ++ii) {
0098           auto daughterid = boxgroupid * kVS + ii;
0099           if (daughterid < daughters->size() && vecCore::MaskLaneAt(inBox, ii)) {
0100 
0101             VPlacedVolume const *nextvolume = (*daughters)[daughterid];
0102             if (ExclV) {
0103               if (exclvol == nextvolume) continue;
0104             }
0105             if (CheckCandidateVolWithDirection<IsAssemblyAware, ModifyState>(nextvolume, localpoint, localdir, state,
0106                                                                              pvol, daughterlocalpoint)) {
0107               return true;
0108             }
0109           }
0110         }
0111       }
0112     }
0113     return false;
0114   }
0115 
0116 public:
0117   VECCORE_ATT_HOST_DEVICE
0118   virtual bool LevelLocate(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint, VPlacedVolume const *&pvol,
0119                            Vector3D<Precision> &daughterlocalpoint) const override
0120   {
0121     return LevelLocateKernel<false, false>(lvol, nullptr, localpoint, nullptr, pvol, daughterlocalpoint);
0122   } // end function
0123 
0124   // version that directly modifies the navigation state
0125   VECCORE_ATT_HOST_DEVICE
0126   virtual bool LevelLocate(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint, NavigationState &outstate,
0127                            Vector3D<Precision> &daughterlocalpoint) const override
0128   {
0129     VPlacedVolume const *pvol;
0130     return LevelLocateKernel<false, true>(lvol, nullptr, localpoint, &outstate, pvol, daughterlocalpoint);
0131   }
0132 
0133   VECCORE_ATT_HOST_DEVICE
0134   virtual bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0135                                   Vector3D<Precision> const &localpoint, VPlacedVolume const *&pvol,
0136                                   Vector3D<Precision> &daughterlocalpoint) const override
0137   {
0138     return LevelLocateKernel<true, false>(lvol, exclvol, localpoint, nullptr, pvol, daughterlocalpoint);
0139   } // end function
0140 
0141   VECCORE_ATT_HOST_DEVICE
0142   virtual bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0143                                   Vector3D<Precision> const &localpoint, Vector3D<Precision> const &localdir,
0144                                   VPlacedVolume const *&pvol, Vector3D<Precision> &daughterlocalpoint) const override
0145   {
0146     return LevelLocateKernelWithDirection<true, false>(lvol, exclvol, localpoint, localdir, nullptr, pvol,
0147                                                        daughterlocalpoint);
0148   }
0149 
0150   static std::string GetClassName() { return "SimpleABBoxLevelLocator"; }
0151   virtual std::string GetName() const override { return GetClassName(); }
0152 
0153   static VLevelLocator const *GetInstance()
0154   {
0155     static TSimpleABBoxLevelLocator instance;
0156     return &instance;
0157   }
0158 
0159 }; // end class declaration
0160 
0161 using SimpleABBoxLevelLocator              = TSimpleABBoxLevelLocator<>;
0162 using SimpleAssemblyAwareABBoxLevelLocator = TSimpleABBoxLevelLocator<true>;
0163 
0164 //// template specializations
0165 // template <>
0166 // inline
0167 // bool TSimpleABBoxLevelLocator<true>::LevelLocate(LogicalVolume const * lvol, Vector3D<Precision> const & localpoint,
0168 //                                                 NavigationState & outstate, Vector3D<Precision> & daughterlocalpoint)
0169 //                                                 const
0170 //{
0171 //    int size;
0172 //    ABBoxManager::ABBoxContainer_v alignedbboxes = fAccelerationStructure.GetABBoxes_v(lvol, size);
0173 
0174 //    auto daughters = lvol->GetDaughtersp();
0175 //    // here the loop is over groups of bounding boxes
0176 //    // it is basically linear but vectorizable search
0177 //    for (int boxgroupid = 0; boxgroupid < size; ++boxgroupid) {
0178 //      using Bool_v = vecCore::Mask_v<ABBoxManager::Float_v>;
0179 //      Bool_v inBox;
0180 //      ABBoxImplementation::ABBoxContainsKernel(alignedbboxes[2 * boxgroupid], alignedbboxes[2 * boxgroupid + 1],
0181 //                                               localpoint, inBox);
0182 //      if (!vecCore::MaskEmpty(inBox)) {
0183 //        constexpr auto kVS = vecCore::VectorSize<ABBoxManager::Float_v>();
0184 //        // TODO: could start directly at first 1 in inBox
0185 //        for (size_t ii = 0; ii < kVS; ++ii) {
0186 //          auto daughterid = boxgroupid * kVS + ii;
0187 //          if (daughterid < daughters->size() && vecCore::MaskLaneAt(inBox, ii)) {
0188 //            VPlacedVolume const *daughter = (*daughters)[daughterid];
0189 //            if (daughter->Contains(localpoint, daughterlocalpoint)) {
0190 //              outstate.Push(daughter);
0191 //              // careful here: we also want to break on external loop
0192 //              return true;
0193 //            }
0194 //          }
0195 //        }
0196 //      }
0197 //    }
0198 //    return false;
0199 //}
0200 
0201 template <>
0202 inline std::string TSimpleABBoxLevelLocator<true>::GetClassName()
0203 {
0204   return "SimpleAssemblyAwareABBoxLevelLocator";
0205 }
0206 } // namespace VECGEOM_IMPL_NAMESPACE
0207 } // namespace vecgeom
0208 
0209 #endif /* NAVIGATION_SIMPLEABBOXLEVELLOCATOR_H_ */