Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #ifndef VECGEOM_CUDA_H
0002 #define VECGEOM_CUDA_H
0003 
0004 #include <memory>
0005 
0006 #include "VecGeom/base/Config.h"
0007 
0008 // Keep compact version of the macros.
0009 // clang-format off
0010 
0011 #if (defined(__CUDACC__) || defined(__NVCC__))
0012   // Compiling with nvcc
0013   #define VECGEOM_IMPL_NAMESPACE cuda
0014   #define VECGEOM_NAMESPACE ::vecgeom
0015   #define VECGEOM_ALIGNED __align__((64))
0016   #define VECGEOM_HOST_FORWARD_DECLARE(X) namespace cxx { X }
0017   #define VECGEOM_DEVICE_FORWARD_DECLARE(X) class __QuietSemi
0018   #define VECGEOM_DEVICE_DECLARE_CONV(classOrStruct,X) class __QuietSemi
0019   #define VECGEOM_DEVICE_DECLARE_NS_CONV(NS,classOrStruct,X,Def) class __QuietSemi
0020   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE(classOrStruct,X,ArgType) class __QuietSemi
0021   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1v(classOrStruct,X,ArgType1,Def1) class __QuietSemi
0022   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1v_1t(classOrStruct,X,ArgType1,ArgType2) class __QuietSemi
0023   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1specv_1t(classOrStruct,X,ArgType1,Def1,ArgType2,Def2,ArgType3) class __QuietSemi
0024   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_2t(classOrStruct,X,ArgType1,ArgType2) class __QuietSemi
0025   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_2v(classOrStruct,X,ArgType1,Def1,ArgType2,Def2) class __QuietSemi
0026   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_2v_1t(classOrStruct,X,ArgType1,Def1,ArgType2,Def2,ArgType3) class __QuietSemi
0027   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1t_2v(classOrStruct,X,ArgType1,ArgType2,Def2,ArgType3,Def3) class __QuietSemi
0028   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_3v(classOrStruct,X,ArgType1,Def1,ArgType2,Def2,ArgType3,Def3) class __QuietSemi
0029   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_4v(classOrStruct,X,ArgType1,Def1,ArgType2,Def2,ArgType3,Def3,ArgType4,Def4) class __QuietSemi
0030   #undef VECGEOM_VC
0031   #undef VECGEOM_CILK
0032   #undef VECGEOM_ROOT
0033   #undef VECGEOM_GEANT4
0034 #else
0035   // Not compiling with NVCC
0036   #define VECGEOM_IMPL_NAMESPACE cxx
0037   #define VECGEOM_NAMESPACE ::vecgeom
0038   #ifdef VECGEOM_ENABLE_CUDA
0039     // CUDA is enabled, but currently compiling regular C++ code.
0040     // This enables methods that interface between C++ and CUDA environments
0041     #define VECGEOM_CUDA_INTERFACE
0042   #endif
0043   namespace vecgeom {
0044      template <typename DataType> struct kCudaType;
0045      template <typename DataType> using CudaType_t = typename kCudaType<DataType>::type_t;
0046      template <> struct kCudaType<float> { using type_t = float; };
0047      template <> struct kCudaType<double> { using type_t = double; };
0048      template <> struct kCudaType<int> { using type_t = int; };
0049      template <> struct kCudaType<size_t> { using type_t = size_t; };
0050      template <typename DataType> struct kCudaType<DataType*> {
0051        using type_t = CudaType_t<DataType>*;
0052      };
0053      template <typename DataType> struct kCudaType<const DataType> {
0054        using type_t = const CudaType_t<DataType>;
0055      };
0056   }
0057   #define VECGEOM_HOST_FORWARD_DECLARE(X)  class __QuietSemi
0058   #define VECGEOM_DEVICE_FORWARD_DECLARE(X)  namespace cuda { X }  class __QuietSemi
0059 
0060   #define VECGEOM_DEVICE_DECLARE_CONV(classOrStruct,X)                 \
0061      namespace cuda { classOrStruct X; }                               \
0062      inline namespace cxx  { classOrStruct X; }                        \
0063      template <> struct kCudaType<cxx::X> { using type_t = cuda::X; }
0064 
0065   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE(classOrStruct,X,ArgType) \
0066      namespace cuda { template <ArgType Arg> classOrStruct X; }         \
0067      inline namespace cxx  { template <ArgType Arg> classOrStruct X; }  \
0068      template <ArgType Arg> struct kCudaType<cxx::X<Arg> >              \
0069      { using type_t = cuda::X<CudaType_t<Arg> >; }
0070 
0071   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_2t(classOrStruct,X,ArgType1,ArgType2)   \
0072      namespace cuda { template <ArgType1 Arg1,ArgType2 Arg2> classOrStruct X; }        \
0073      inline namespace cxx  { template <ArgType1 Arg1,ArgType2 Arg2> classOrStruct X; } \
0074      template <ArgType1 Arg1,ArgType2 Arg2> struct kCudaType<cxx::X<Arg1,Arg2> >       \
0075      { using type_t = cuda::X<CudaType_t<Arg1>, CudaType_t<Arg2> >; }
0076 
0077   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1v_1t(classOrStruct,X,ArgType1,ArgType2) \
0078      namespace cuda { template <ArgType1 Arg1,ArgType2 Arg2> classOrStruct X; }         \
0079      inline namespace cxx  { template <ArgType1 Arg1,ArgType2 Arg2> classOrStruct X; }  \
0080      template <ArgType1 Arg1,ArgType2 Arg2> struct kCudaType<cxx::X<Arg1,Arg2> >        \
0081      { using type_t = cuda::X<Arg1, CudaType_t<Arg2> >; }
0082 
0083 #ifdef VECGEOM_CUDA_VOLUME_SPECIALIZATION
0084 
0085   #define VECGEOM_DEVICE_DECLARE_NS_CONV(NS,classOrStruct,X,Def)               \
0086      namespace cuda { namespace NS { classOrStruct X; } }                      \
0087      inline namespace cxx { namespace NS { classOrStruct X; } }                \
0088      template <> struct kCudaType<cxx::NS::X> { using type_t = cuda::NS::X; }
0089 
0090   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1v(classOrStruct,X,ArgType1,Def1) \
0091      namespace cuda { template <ArgType1 Arg1> classOrStruct X; }                \
0092      inline namespace cxx  { template <ArgType1 Arg1> classOrStruct X; }         \
0093      template <ArgType1 Arg1> struct kCudaType<cxx::X<Arg1> >                    \
0094      { using type_t = cuda::X<Arg>; }
0095   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1specv_1t(classOrStruct,X,ArgType1,ArgType2) \
0096      namespace cuda { template <ArgType1 Arg1,ArgType2 Arg2> classOrStruct X; }             \
0097      inline namespace cxx  { template <ArgType1 Arg1,ArgType2 Arg2> classOrStruct X; }      \
0098      template <ArgType1 Arg1,ArgType2 Arg2> struct kCudaType<cxx::X<Arg1,Arg2> >            \
0099      { using type_t = cuda::X<Arg1, CudaType_t<Arg2> >; }
0100   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_2v(classOrStruct,X,ArgType1,Def1,ArgType2,Def2) \
0101      namespace cuda { template <ArgType1 Arg1,ArgType2 Arg2> classOrStruct X; }                \
0102      inline namespace cxx  { template <ArgType1 Arg1,ArgType2 Arg2> classOrStruct X; }         \
0103      template <ArgType1 Arg1,ArgType2 Arg2> struct kCudaType<cxx::X<Arg1,Arg2> >               \
0104      { using type_t = cuda::X<Arg1,Arg2 >; }
0105   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_2v_1t(classOrStruct,X,ArgType1,Def1,ArgType2,Def2,ArgType3) \
0106      namespace cuda { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> classOrStruct X; }              \
0107      inline namespace cxx  { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> classOrStruct X; }       \
0108      template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> struct kCudaType<cxx::X<Arg1,Arg2,Arg3> >        \
0109      { using type_t = cuda::X<Arg1, Arg2, CudaType_t<Arg3> >; }
0110   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1t_2v(classOrStruct,X,ArgType1,ArgType2,Def2,ArgType3,Def3) \
0111      namespace cuda { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> classOrStruct X; }              \
0112      inline namespace cxx  { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> classOrStruct X; }       \
0113      template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> struct kCudaType<cxx::X<Arg1,Arg2,Arg3> >        \
0114      { using type_t = cuda::X<CudaType_t<Arg1>, Arg2, Arg3 >; }
0115   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_3v(classOrStruct,X,ArgType1,Def1,ArgType2,Def2,ArgType3,Def3) \
0116      namespace cuda { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> classOrStruct X; }                \
0117      inline namespace cxx  { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> classOrStruct X; }         \
0118      template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> struct kCudaType<cxx::X<Arg1,Arg2,Arg3> >          \
0119      { using type_t = cuda::X<Arg1,Arg2,Arg3 >; }
0120 
0121   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_4v(classOrStruct,X,ArgType1,Def1,ArgType2,Def2,ArgType3,Def3,ArgType4,Def4) \
0122     namespace cuda { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3,ArgType4 Arg4> classOrStruct X; }                 \
0123     inline namespace cxx  { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3,ArgType4 Arg4> classOrStruct X; }          \
0124     template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3,ArgType4 Arg4> struct kCudaType<cxx::X<Arg1,Arg2,Arg3,Arg4> >      \
0125     { using type_t = cuda::X<Arg1,Arg2,Arg3,Arg4 >; }
0126 
0127 #else // VECGEOM_CUDA_VOLUME_SPECIALIZATION
0128 
0129   #define VECGEOM_DEVICE_DECLARE_NS_CONV(NS,classOrStruct,X,Def)                 \
0130      namespace cuda { namespace NS { classOrStruct Def; } }                      \
0131      inline namespace cxx { namespace NS { classOrStruct X; } }                  \
0132      template <> struct kCudaType<cxx::NS::X> { using type_t = cuda::NS::Def; }
0133 
0134   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1v(classOrStruct,X,ArgType1,Def1) \
0135      namespace cuda { template <ArgType1 Arg1> classOrStruct X; }                \
0136      inline namespace cxx  { template <ArgType1 Arg1> classOrStruct X; }         \
0137      template <ArgType1 Arg1> struct kCudaType<cxx::X<Arg1> >                    \
0138      { using type_t = cuda::X<Def1>; }
0139   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1specv_1t(classOrStruct,X,ArgType1,Def1,ArgType2) \
0140      namespace cuda { template <ArgType1 Arg1,ArgType2 Arg2> classOrStruct X; }             \
0141      inline namespace cxx  { template <ArgType1 Arg1,ArgType2 Arg2> classOrStruct X; }      \
0142      template <ArgType1 Arg1,ArgType2 Arg2> struct kCudaType<cxx::X<Arg1,Arg2> >            \
0143      { using type_t = cuda::X<Def1, CudaType_t<Arg2> >; }
0144   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_2v(classOrStruct,X,ArgType1,Def1,ArgType2,Def2) \
0145      namespace cuda { template <ArgType1 Arg1,ArgType2 Arg2> classOrStruct X; }                \
0146      inline namespace cxx  { template <ArgType1 Arg1,ArgType2 Arg2> classOrStruct X; }         \
0147      template <ArgType1 Arg1,ArgType2 Arg2> struct kCudaType<cxx::X<Arg1,Arg2> >               \
0148      { using type_t = cuda::X<Def1, Def2 >; }
0149   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_2v_1t(classOrStruct,X,ArgType1,Def1,ArgType2,Def2,ArgType3) \
0150      namespace cuda { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> classOrStruct X; }              \
0151      inline namespace cxx  { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> classOrStruct X; }       \
0152      template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> struct kCudaType<cxx::X<Arg1,Arg2,Arg3> >        \
0153      { using type_t = cuda::X<Def1, Def2, CudaType_t<Arg3> >; }
0154   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1t_2v(classOrStruct,X,ArgType1,ArgType2,Def2,ArgType3,Def3) \
0155      namespace cuda { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> classOrStruct X; }              \
0156      inline namespace cxx  { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> classOrStruct X; }       \
0157      template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> struct kCudaType<cxx::X<Arg1,Arg2,Arg3> >        \
0158      { using type_t = cuda::X<CudaType_t<Arg1>, Def2, Def3 >; }
0159   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_3v(classOrStruct,X,ArgType1,Def1,ArgType2,Def2,ArgType3,Def3) \
0160      namespace cuda { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> classOrStruct X; }                \
0161      inline namespace cxx  { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> classOrStruct X; }         \
0162      template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3> struct kCudaType<cxx::X<Arg1,Arg2,Arg3> >          \
0163      { using type_t = cuda::X<Def1,Def2,Def3 >; }
0164   #define VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_4v(classOrStruct,X,ArgType1,Def1,ArgType2,Def2,ArgType3,Def3,ArgType4,Def4) \
0165      namespace cuda { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3,ArgType4 Arg4> classOrStruct X; }                \
0166      inline namespace cxx  { template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3,ArgType4 Arg4> classOrStruct X; }         \
0167      template <ArgType1 Arg1,ArgType2 Arg2,ArgType3 Arg3,ArgType4 Arg4> struct kCudaType<cxx::X<Arg1,Arg2,Arg3,Arg4> >     \
0168      { using type_t = cuda::X<Def1,Def2,Def3,Def4 >; }
0169 
0170 #endif // VECGEOM_CUDA_VOLUME_SPECIALIZATION
0171 
0172 /* Instead of multiple macro, when we have auto expansion of Template pack we could use:
0173 template <typename... Arguments>
0174 struct kCudaType<cxx::BoxImplementation<Arguments...>  >
0175    { using type_t = typename cuda::BoxImplementation<CudaType_t<Arguments...> >; };
0176 */
0177 #endif
0178 
0179 // clang-format on
0180 
0181 namespace vecgeom {
0182 inline namespace VECGEOM_IMPL_NAMESPACE {
0183 
0184 #ifndef VECCORE_CUDA
0185 using std::unique_ptr;
0186 #else
0187 template <typename T>
0188 class unique_ptr {
0189   T *fValue;
0190 
0191 public:
0192   VECCORE_ATT_HOST_DEVICE
0193   unique_ptr(T *in) : fValue(in) {}
0194 
0195   VECCORE_ATT_HOST_DEVICE
0196   ~unique_ptr() { delete fValue; }
0197 
0198   VECCORE_ATT_HOST_DEVICE
0199   T *operator->() { return fValue; }
0200 };
0201 
0202 template <typename T>
0203 class unique_ptr<T[]> {
0204   T *fValue;
0205 
0206 public:
0207   VECCORE_ATT_HOST_DEVICE
0208   unique_ptr(T *in) : fValue(in) {}
0209 
0210   VECCORE_ATT_HOST_DEVICE
0211   ~unique_ptr() { delete[] fValue; }
0212 
0213   VECCORE_ATT_HOST_DEVICE
0214   T &operator[](size_t idx) { return fValue[idx]; }
0215 };
0216 #endif
0217 }
0218 } // namespace vecgeom
0219 
0220 #endif