@@ -24,6 +24,7 @@ constexpr int kUsmDeviceRedzoneMagic = (char)0x81;
2424constexpr int kUsmHostRedzoneMagic = (char )0x82 ;
2525constexpr int kUsmSharedRedzoneMagic = (char )0x83 ;
2626constexpr int kMemBufferRedzoneMagic = (char )0x84 ;
27+ constexpr int kDeviceGlobalRedZoneMagic = (char )0x85 ;
2728
2829constexpr auto kSPIR_AsanShadowMemoryGlobalStart =
2930 " __AsanShadowMemoryGlobalStart" ;
@@ -36,6 +37,9 @@ constexpr auto kSPIR_DeviceType = "__DeviceType";
3637
3738constexpr auto kSPIR_DeviceSanitizerReportMem = " __DeviceSanitizerReportMem" ;
3839
40+ constexpr auto kSPIR_AsanDeviceGlobalCount = " __AsanDeviceGlobalCount" ;
41+ constexpr auto kSPIR_AsanDeviceGlobalMetadata = " __AsanDeviceGlobalMetadata" ;
42+
3943DeviceSanitizerReport SPIR_DeviceSanitizerReportMem;
4044
4145uptr MemToShadow_CPU (uptr USM_SHADOW_BASE, uptr UPtr) {
@@ -78,6 +82,19 @@ ur_program_handle_t getProgram(ur_kernel_handle_t Kernel) {
7882 return Program;
7983}
8084
85+ void getProgramDevices (ur_program_handle_t Program,
86+ std::vector<ur_device_handle_t > &Devices) {
87+ size_t PropSize;
88+ [[maybe_unused]] ur_result_t Result = context.urDdiTable .Program .pfnGetInfo (
89+ Program, UR_PROGRAM_INFO_DEVICES, 0 , nullptr , &PropSize);
90+ assert (Result == UR_RESULT_SUCCESS);
91+
92+ Devices.resize (PropSize / sizeof (ur_device_handle_t ));
93+ Result = context.urDdiTable .Program .pfnGetInfo (
94+ Program, UR_PROGRAM_INFO_DEVICES, PropSize, Devices.data (), nullptr );
95+ assert (Result == UR_RESULT_SUCCESS);
96+ }
97+
8198size_t getLocalMemorySize (ur_device_handle_t Device) {
8299 size_t LocalMemorySize;
83100 [[maybe_unused]] auto Result = context.urDdiTable .Device .pfnGetInfo (
@@ -124,7 +141,7 @@ SanitizerInterceptor::~SanitizerInterceptor() {
124141ur_result_t SanitizerInterceptor::allocateMemory (
125142 ur_context_handle_t Context, ur_device_handle_t Device,
126143 const ur_usm_desc_t *Properties, ur_usm_pool_handle_t Pool, size_t Size,
127- void **ResultPtr, USMMemoryType Type) {
144+ void **ResultPtr, AllocType Type) {
128145 auto Alignment = Properties->align ;
129146 assert (Alignment == 0 || IsPowerOfTwo (Alignment));
130147
@@ -147,13 +164,13 @@ ur_result_t SanitizerInterceptor::allocateMemory(
147164
148165 void *Allocated = nullptr ;
149166
150- if (Type == USMMemoryType::DEVICE ) {
167+ if (Type == AllocType::DEVICE_USM ) {
151168 UR_CALL (context.urDdiTable .USM .pfnDeviceAlloc (
152169 Context, Device, Properties, Pool, NeededSize, &Allocated));
153- } else if (Type == USMMemoryType::HOST ) {
170+ } else if (Type == AllocType::HOST_USM ) {
154171 UR_CALL (context.urDdiTable .USM .pfnHostAlloc (Context, Properties, Pool,
155172 NeededSize, &Allocated));
156- } else if (Type == USMMemoryType::SHARE ) {
173+ } else if (Type == AllocType::SHARED_USM ) {
157174 UR_CALL (context.urDdiTable .USM .pfnSharedAlloc (
158175 Context, Device, Properties, Pool, NeededSize, &Allocated));
159176 } else {
@@ -173,31 +190,31 @@ ur_result_t SanitizerInterceptor::allocateMemory(
173190
174191 *ResultPtr = reinterpret_cast <void *>(UserBegin);
175192
176- auto AllocInfo = std::make_shared<USMAllocInfo >(
177- USMAllocInfo {AllocBegin, UserBegin, UserEnd, NeededSize, Type});
193+ auto AI = std::make_shared<AllocInfo >(
194+ AllocInfo {AllocBegin, UserBegin, UserEnd, NeededSize, Type});
178195
179196 // For updating shadow memory
180197 if (DeviceInfo) { // device/shared USM
181198 std::scoped_lock<ur_shared_mutex> Guard (DeviceInfo->Mutex );
182- DeviceInfo->AllocInfos .emplace_back (AllocInfo );
199+ DeviceInfo->AllocInfos .emplace_back (AI );
183200 } else { // host USM's AllocInfo needs to insert into all devices
184201 for (auto &pair : ContextInfo->DeviceMap ) {
185202 auto DeviceInfo = pair.second ;
186203 std::scoped_lock<ur_shared_mutex> Guard (DeviceInfo->Mutex );
187- DeviceInfo->AllocInfos .emplace_back (AllocInfo );
204+ DeviceInfo->AllocInfos .emplace_back (AI );
188205 }
189206 }
190207
191208 // For memory release
192209 {
193210 std::scoped_lock<ur_shared_mutex> Guard (ContextInfo->Mutex );
194- ContextInfo->AllocatedUSMMap [AllocBegin] = std::move (AllocInfo );
211+ ContextInfo->AllocatedUSMMap [AllocBegin] = std::move (AI );
195212 }
196213
197214 context.logger .info (
198215 " AllocInfos(AllocBegin={}, User={}-{}, NeededSize={}, Type={})" ,
199216 (void *)AllocBegin, (void *)UserBegin, (void *)UserEnd, NeededSize,
200- Type);
217+ ToString ( Type) );
201218
202219 return UR_RESULT_SUCCESS;
203220}
@@ -285,8 +302,8 @@ void SanitizerInterceptor::postLaunchKernel(ur_kernel_handle_t Kernel,
285302 KernelName = DemangleName (KernelName);
286303
287304 context.logger .always (" \n ====ERROR: DeviceSanitizer: {} on {}" ,
288- DeviceSanitizerFormat (AH->ErrorType ),
289- DeviceSanitizerFormat (AH->MemoryType ));
305+ ToString (AH->ErrorType ),
306+ ToString (AH->MemoryType ));
290307 context.logger .always (
291308 " {} of size {} at kernel <{}> LID({}, {}, {}) GID({}, "
292309 " {}, {})" ,
@@ -478,7 +495,7 @@ ur_result_t SanitizerInterceptor::enqueueMemSetShadow(
478495// / ref: https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm#mapping
479496ur_result_t SanitizerInterceptor::enqueueAllocInfo (
480497 ur_context_handle_t Context, ur_device_handle_t Device,
481- ur_queue_handle_t Queue, std::shared_ptr<USMAllocInfo > &AllocInfo,
498+ ur_queue_handle_t Queue, std::shared_ptr<AllocInfo > &AllocInfo,
482499 ur_event_handle_t &LastEvent) {
483500 // Init zero
484501 UR_CALL (enqueueMemSetShadow (Context, Device, Queue, AllocInfo->AllocBegin ,
@@ -499,18 +516,21 @@ ur_result_t SanitizerInterceptor::enqueueAllocInfo(
499516
500517 int ShadowByte;
501518 switch (AllocInfo->Type ) {
502- case USMMemoryType::HOST :
519+ case AllocType::HOST_USM :
503520 ShadowByte = kUsmHostRedzoneMagic ;
504521 break ;
505- case USMMemoryType::DEVICE :
522+ case AllocType::DEVICE_USM :
506523 ShadowByte = kUsmDeviceRedzoneMagic ;
507524 break ;
508- case USMMemoryType::SHARE :
525+ case AllocType::SHARED_USM :
509526 ShadowByte = kUsmSharedRedzoneMagic ;
510527 break ;
511- case USMMemoryType ::MEM_BUFFER:
528+ case AllocType ::MEM_BUFFER:
512529 ShadowByte = kMemBufferRedzoneMagic ;
513530 break ;
531+ case AllocType::DEVICE_GLOBAL:
532+ ShadowByte = kDeviceGlobalRedZoneMagic ;
533+ break ;
514534 default :
515535 ShadowByte = 0xff ;
516536 assert (false && " Unknow AllocInfo Type" );
@@ -556,6 +576,62 @@ ur_result_t SanitizerInterceptor::updateShadowMemory(ur_queue_handle_t Queue) {
556576 return UR_RESULT_SUCCESS;
557577}
558578
579+ ur_result_t
580+ SanitizerInterceptor::registerDeviceGlobals (ur_context_handle_t Context,
581+ ur_program_handle_t Program) {
582+ std::vector<ur_device_handle_t > Devices;
583+ getProgramDevices (Program, Devices);
584+
585+ for (auto Device : Devices) {
586+ ur_queue_handle_t Queue;
587+ ur_result_t Result = context.urDdiTable .Queue .pfnCreate (
588+ Context, Device, nullptr , &Queue);
589+ if (Result != UR_RESULT_SUCCESS) {
590+ context.logger .error (" Failed to create command queue: {}" , Result);
591+ return Result;
592+ }
593+
594+ uint64_t NumOfDeviceGlobal;
595+ Result = context.urDdiTable .Enqueue .pfnDeviceGlobalVariableRead (
596+ Queue, Program, kSPIR_AsanDeviceGlobalCount , true ,
597+ sizeof (NumOfDeviceGlobal), 0 , &NumOfDeviceGlobal, 0 , nullptr ,
598+ nullptr );
599+ if (Result == UR_RESULT_ERROR_INVALID_ARGUMENT) {
600+ context.logger .info (" No device globals" );
601+ continue ;
602+ } else if (Result != UR_RESULT_SUCCESS) {
603+ context.logger .error (" Device Global[{}] Read Failed: {}" ,
604+ kSPIR_AsanDeviceGlobalCount , Result);
605+ return Result;
606+ }
607+
608+ std::vector<DeviceGlobalInfo> GVInfos (NumOfDeviceGlobal);
609+ Result = context.urDdiTable .Enqueue .pfnDeviceGlobalVariableRead (
610+ Queue, Program, kSPIR_AsanDeviceGlobalMetadata , true ,
611+ sizeof (DeviceGlobalInfo) * NumOfDeviceGlobal, 0 , &GVInfos[0 ], 0 ,
612+ nullptr , nullptr );
613+ if (Result != UR_RESULT_SUCCESS) {
614+ context.logger .error (" Device Global[{}] Read Failed: {}" ,
615+ kSPIR_AsanDeviceGlobalMetadata , Result);
616+ return Result;
617+ }
618+
619+ auto ContextInfo = getContextInfo (Context);
620+ auto DeviceInfo = ContextInfo->getDeviceInfo (Device);
621+ for (size_t i = 0 ; i < NumOfDeviceGlobal; i++) {
622+ auto AI = std::make_shared<AllocInfo>(AllocInfo{
623+ GVInfos[i].Addr , GVInfos[i].Addr ,
624+ GVInfos[i].Addr + GVInfos[i].Size , GVInfos[i].SizeWithRedZone ,
625+ AllocType::DEVICE_GLOBAL});
626+
627+ std::scoped_lock<ur_shared_mutex> Guard (DeviceInfo->Mutex );
628+ DeviceInfo->AllocInfos .emplace_back (AI);
629+ }
630+ }
631+
632+ return UR_RESULT_SUCCESS;
633+ }
634+
559635ur_result_t SanitizerInterceptor::insertContext (ur_context_handle_t Context) {
560636 auto ContextInfo = std::make_shared<ur_sanitizer_layer::ContextInfo>();
561637
0 commit comments