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
0009
0010
0011 #if (defined(__CUDACC__) || defined(__NVCC__))
0012
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
0036 #define VECGEOM_IMPL_NAMESPACE cxx
0037 #define VECGEOM_NAMESPACE ::vecgeom
0038 #ifdef VECGEOM_ENABLE_CUDA
0039
0040
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
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
0171
0172
0173
0174
0175
0176
0177 #endif
0178
0179
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 }
0219
0220 #endif