@@ -149,16 +149,18 @@ void GPUReconstructionCUDABackend::runKernelBackendInternal(krnlSetup& _xyz, con
149149 if (mProcessingSettings .enableRTC ) {
150150 auto & x = _xyz.x ;
151151 auto & y = _xyz.y ;
152+ const void * pArgs[sizeof ...(Args) + 3 ]; // 3 is max: cons mem + y.start + y.num
153+ int arg_offset = 0 ;
154+ #ifdef GPUCA_NO_CONSTANT_MEMORY
155+ arg_offset = 1 ;
156+ pArgs[0 ] = &mDeviceConstantMemRTC [0 ];
157+ #endif
158+ pArgs[arg_offset] = &y.start ;
159+ getArgPtrs (&pArgs[arg_offset + 1 + (y.num > 1 )], args...);
152160 if (y.num <= 1 ) {
153- const void * pArgs[sizeof ...(Args) + 1 ];
154- pArgs[0 ] = &y.start ;
155- getArgPtrs (&pArgs[1 ], args...);
156161 GPUFailedMsg (cuLaunchKernel (*mInternals ->rtcFunctions [mInternals ->getRTCkernelNum <false , T, I>()], x.nBlocks , 1 , 1 , x.nThreads , 1 , 1 , 0 , mInternals ->Streams [x.stream ], (void **)pArgs, nullptr ));
157162 } else {
158- const void * pArgs[sizeof ...(Args) + 2 ];
159- pArgs[0 ] = &y.start ;
160- pArgs[1 ] = &y.num ;
161- getArgPtrs (&pArgs[2 ], args...);
163+ pArgs[arg_offset + 1 ] = &y.num ;
162164 GPUFailedMsg (cuLaunchKernel (*mInternals ->rtcFunctions [mInternals ->getRTCkernelNum <true , T, I>()], x.nBlocks , 1 , 1 , x.nThreads , 1 , 1 , 0 , mInternals ->Streams [x.stream ], (void **)pArgs, nullptr ));
163165 }
164166 } else {
@@ -461,17 +463,24 @@ int GPUReconstructionCUDABackend::InitDevice_Runtime()
461463#undef GPUCA_KRNL_LOAD_multi
462464 }
463465#endif
464- void * devPtrConstantMem;
466+ void * devPtrConstantMem, *devPtrConstantMemRTC ;
465467#ifndef GPUCA_NO_CONSTANT_MEMORY
468+ GPUFailedMsg (cudaGetSymbolAddress (&devPtrConstantMem, gGPUConstantMemBuffer ));
466469 if (mProcessingSettings .enableRTC ) {
467- GPUFailedMsg (cuModuleGetGlobal ((CUdeviceptr*)&devPtrConstantMem, nullptr , mInternals ->rtcModule , " gGPUConstantMemBuffer" ));
468- } else {
469- GPUFailedMsg (cudaGetSymbolAddress (&devPtrConstantMem, gGPUConstantMemBuffer ));
470+ GPUFailedMsg (cuModuleGetGlobal ((CUdeviceptr*)&devPtrConstantMemRTC, nullptr , mInternals ->rtcModule , " gGPUConstantMemBuffer" ));
470471 }
471472#else
472473 GPUFailedMsg (cudaMalloc (&devPtrConstantMem, gGPUConstantMemBufferSize ));
474+ if (mProcessingSettings .enableRTC ) {
475+ GPUFailedMsg (cudaMalloc (&devPtrConstantMemRTC, gGPUConstantMemBufferSize ));
476+ }
473477#endif
474478 mDeviceConstantMem = (GPUConstantMem*)devPtrConstantMem;
479+ mDeviceConstantMem = (GPUConstantMem*)devPtrConstantMemRTC; // TODO: This is a hack, since the memory is sometimes addressed via the pointer from the kernel, should be made consistent!
480+ if (mProcessingSettings .enableRTC ) {
481+ mDeviceConstantMemRTC .resize (1 );
482+ mDeviceConstantMemRTC [0 ] = devPtrConstantMemRTC;
483+ }
475484 } else {
476485 GPUReconstructionCUDABackend* master = dynamic_cast <GPUReconstructionCUDABackend*>(mMaster );
477486 mDeviceId = master->mDeviceId ;
@@ -480,6 +489,8 @@ int GPUReconstructionCUDABackend::InitDevice_Runtime()
480489 mMaxThreads = master->mMaxThreads ;
481490 mDeviceName = master->mDeviceName ;
482491 mDeviceConstantMem = master->mDeviceConstantMem ;
492+ mDeviceConstantMemRTC .resize (master->mDeviceConstantMemRTC .size ());
493+ std::copy (master->mDeviceConstantMemRTC .begin (), master->mDeviceConstantMemRTC .end (), mDeviceConstantMemRTC .begin ());
483494 mInternals = master->mInternals ;
484495 GPUFailedMsgI (cuCtxPushCurrent (mInternals ->CudaContext ));
485496 }
@@ -522,6 +533,10 @@ int GPUReconstructionCUDABackend::ExitDevice_Runtime()
522533 GPUFailedMsgI (cudaFree (mDeviceMemoryBase ));
523534#ifdef GPUCA_NO_CONSTANT_MEMORY
524535 GPUFailedMsgI (cudaFree (mDeviceConstantMem ));
536+ for (unsigned int i = 0 ; i < mDeviceConstantMemRTC .size (); i++) {
537+ GPUFailedMsgI (cudaFree (mDeviceConstantMemRTC [i]));
538+ }
539+ mDeviceConstantMemRTC .clear ();
525540#endif
526541
527542 for (int i = 0 ; i < mNStreams ; i++) {
@@ -584,17 +599,19 @@ size_t GPUReconstructionCUDABackend::TransferMemoryInternal(GPUMemoryResource* r
584599
585600size_t GPUReconstructionCUDABackend::WriteToConstantMemory (size_t offset, const void * src, size_t size, int stream, deviceEvent* ev)
586601{
602+ int iFirst = 0 ;
587603#ifndef GPUCA_NO_CONSTANT_MEMORY
588604 if (stream == -1 ) {
589605 GPUFailedMsg (cudaMemcpyToSymbol (gGPUConstantMemBuffer , src, size, offset, cudaMemcpyHostToDevice));
590606 } else {
591607 GPUFailedMsg (cudaMemcpyToSymbolAsync (gGPUConstantMemBuffer , src, size, offset, cudaMemcpyHostToDevice, mInternals ->Streams [stream]));
592608 }
593- if ( mProcessingSettings . enableRTC )
609+ iFirst = 1 ;
594610#endif
595- {
596- std::unique_ptr<GPUParamRTC> tmpParam;
597- if (mProcessingSettings .rtcConstexpr ) {
611+ int iLast = 1 + mDeviceConstantMemRTC .size ();
612+ std::unique_ptr<GPUParamRTC> tmpParam;
613+ for (int i = iFirst; i < iLast; i++) {
614+ if (i == 1 ) { // First time we copy into the RTC constant mem, need to prepare
598615 if (offset < sizeof (GPUParam) && (offset != 0 || size > sizeof (GPUParam))) {
599616 throw std::runtime_error (" Invalid write to constant memory, crossing GPUParam border" );
600617 }
@@ -607,10 +624,11 @@ size_t GPUReconstructionCUDABackend::WriteToConstantMemory(size_t offset, const
607624 offset = offset - sizeof (GPUParam) + sizeof (GPUParamRTC);
608625 }
609626 }
627+ void * basePtr = i ? mDeviceConstantMemRTC [i - 1 ] : mDeviceConstantMem ;
610628 if (stream == -1 ) {
611- GPUFailedMsg (cudaMemcpy (((char *)mDeviceConstantMem ) + offset, src, size, cudaMemcpyHostToDevice));
629+ GPUFailedMsg (cudaMemcpy (((char *)basePtr ) + offset, src, size, cudaMemcpyHostToDevice));
612630 } else {
613- GPUFailedMsg (cudaMemcpyAsync (((char *)mDeviceConstantMem ) + offset, src, size, cudaMemcpyHostToDevice, mInternals ->Streams [stream]));
631+ GPUFailedMsg (cudaMemcpyAsync (((char *)basePtr ) + offset, src, size, cudaMemcpyHostToDevice, mInternals ->Streams [stream]));
614632 }
615633 }
616634 if (ev && stream != -1 ) {
0 commit comments