Skip to content

Commit d18d523

Browse files
authored
Merge pull request #2415 from AllanZyne/review/yang/fix_metadata_assert
[DeviceASAN] Fix ASAN with kernel assert
2 parents c45de9a + 05f94a8 commit d18d523

File tree

5 files changed

+55
-58
lines changed

5 files changed

+55
-58
lines changed

source/loader/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ if(UR_ENABLE_SANITIZER)
136136
${CMAKE_CURRENT_SOURCE_DIR}/layers/sanitizer/asan/asan_buffer.cpp
137137
${CMAKE_CURRENT_SOURCE_DIR}/layers/sanitizer/asan/asan_buffer.hpp
138138
${CMAKE_CURRENT_SOURCE_DIR}/layers/sanitizer/asan/asan_ddi.cpp
139+
${CMAKE_CURRENT_SOURCE_DIR}/layers/sanitizer/asan/asan_ddi.hpp
139140
${CMAKE_CURRENT_SOURCE_DIR}/layers/sanitizer/asan/asan_interceptor.cpp
140141
${CMAKE_CURRENT_SOURCE_DIR}/layers/sanitizer/asan/asan_interceptor.hpp
141142
${CMAKE_CURRENT_SOURCE_DIR}/layers/sanitizer/asan/asan_libdevice.hpp

source/loader/layers/sanitizer/asan/asan_ddi.cpp

+13-34
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,6 @@ ur_result_t setupContext(ur_context_handle_t Context, uint32_t numDevices,
5252
return UR_RESULT_SUCCESS;
5353
}
5454

55-
bool isInstrumentedKernel(ur_kernel_handle_t hKernel) {
56-
auto hProgram = GetProgram(hKernel);
57-
auto PI = getAsanInterceptor()->getProgramInfo(hProgram);
58-
if (PI == nullptr) {
59-
return false;
60-
}
61-
return PI->isKernelInstrumented(hKernel);
62-
}
63-
6455
} // namespace
6556

6657
///////////////////////////////////////////////////////////////////////////////
@@ -470,15 +461,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueKernelLaunch(
470461

471462
getContext()->logger.debug("==== urEnqueueKernelLaunch");
472463

473-
if (!isInstrumentedKernel(hKernel)) {
474-
return pfnKernelLaunch(hQueue, hKernel, workDim, pGlobalWorkOffset,
475-
pGlobalWorkSize, pLocalWorkSize,
476-
numEventsInWaitList, phEventWaitList, phEvent);
477-
}
478-
479464
LaunchInfo LaunchInfo(GetContext(hQueue), GetDevice(hQueue),
480465
pGlobalWorkSize, pLocalWorkSize, pGlobalWorkOffset,
481466
workDim);
467+
UR_CALL(LaunchInfo.Data.syncToDevice(hQueue));
482468

483469
UR_CALL(getAsanInterceptor()->preLaunchKernel(hKernel, hQueue, LaunchInfo));
484470

@@ -1366,9 +1352,7 @@ __urdlllocal ur_result_t UR_APICALL urKernelCreate(
13661352
getContext()->logger.debug("==== urKernelCreate");
13671353

13681354
UR_CALL(pfnCreate(hProgram, pKernelName, phKernel));
1369-
if (isInstrumentedKernel(*phKernel)) {
1370-
UR_CALL(getAsanInterceptor()->insertKernel(*phKernel));
1371-
}
1355+
UR_CALL(getAsanInterceptor()->insertKernel(*phKernel));
13721356

13731357
return UR_RESULT_SUCCESS;
13741358
}
@@ -1389,9 +1373,7 @@ __urdlllocal ur_result_t UR_APICALL urKernelRetain(
13891373
UR_CALL(pfnRetain(hKernel));
13901374

13911375
auto KernelInfo = getAsanInterceptor()->getKernelInfo(hKernel);
1392-
if (KernelInfo) {
1393-
KernelInfo->RefCount++;
1394-
}
1376+
KernelInfo->RefCount++;
13951377

13961378
return UR_RESULT_SUCCESS;
13971379
}
@@ -1411,10 +1393,8 @@ __urdlllocal ur_result_t urKernelRelease(
14111393
UR_CALL(pfnRelease(hKernel));
14121394

14131395
auto KernelInfo = getAsanInterceptor()->getKernelInfo(hKernel);
1414-
if (KernelInfo) {
1415-
if (--KernelInfo->RefCount == 0) {
1416-
UR_CALL(getAsanInterceptor()->eraseKernel(hKernel));
1417-
}
1396+
if (--KernelInfo->RefCount == 0) {
1397+
UR_CALL(getAsanInterceptor()->eraseKernel(hKernel));
14181398
}
14191399

14201400
return UR_RESULT_SUCCESS;
@@ -1440,11 +1420,10 @@ __urdlllocal ur_result_t UR_APICALL urKernelSetArgValue(
14401420
getContext()->logger.debug("==== urKernelSetArgValue");
14411421

14421422
std::shared_ptr<MemBuffer> MemBuffer;
1443-
std::shared_ptr<KernelInfo> KernelInfo;
14441423
if (argSize == sizeof(ur_mem_handle_t) &&
14451424
(MemBuffer = getAsanInterceptor()->getMemBuffer(
1446-
*ur_cast<const ur_mem_handle_t *>(pArgValue))) &&
1447-
(KernelInfo = getAsanInterceptor()->getKernelInfo(hKernel))) {
1425+
*ur_cast<const ur_mem_handle_t *>(pArgValue)))) {
1426+
auto KernelInfo = getAsanInterceptor()->getKernelInfo(hKernel);
14481427
std::scoped_lock<ur_shared_mutex> Guard(KernelInfo->Mutex);
14491428
KernelInfo->BufferArgs[argIndex] = std::move(MemBuffer);
14501429
} else {
@@ -1473,9 +1452,8 @@ __urdlllocal ur_result_t UR_APICALL urKernelSetArgMemObj(
14731452
getContext()->logger.debug("==== urKernelSetArgMemObj");
14741453

14751454
std::shared_ptr<MemBuffer> MemBuffer;
1476-
std::shared_ptr<KernelInfo> KernelInfo;
1477-
if ((MemBuffer = getAsanInterceptor()->getMemBuffer(hArgValue)) &&
1478-
(KernelInfo = getAsanInterceptor()->getKernelInfo(hKernel))) {
1455+
if ((MemBuffer = getAsanInterceptor()->getMemBuffer(hArgValue))) {
1456+
auto KernelInfo = getAsanInterceptor()->getKernelInfo(hKernel);
14791457
std::scoped_lock<ur_shared_mutex> Guard(KernelInfo->Mutex);
14801458
KernelInfo->BufferArgs[argIndex] = std::move(MemBuffer);
14811459
} else {
@@ -1505,7 +1483,8 @@ __urdlllocal ur_result_t UR_APICALL urKernelSetArgLocal(
15051483
"==== urKernelSetArgLocal (argIndex={}, argSize={})", argIndex,
15061484
argSize);
15071485

1508-
if (auto KI = getAsanInterceptor()->getKernelInfo(hKernel)) {
1486+
{
1487+
auto KI = getAsanInterceptor()->getKernelInfo(hKernel);
15091488
std::scoped_lock<ur_shared_mutex> Guard(KI->Mutex);
15101489
// TODO: get local variable alignment
15111490
auto argSizeWithRZ = GetSizeAndRedzoneSizeForLocal(
@@ -1542,8 +1521,8 @@ __urdlllocal ur_result_t UR_APICALL urKernelSetArgPointer(
15421521
pArgValue);
15431522

15441523
std::shared_ptr<KernelInfo> KI;
1545-
if (getAsanInterceptor()->getOptions().DetectKernelArguments &&
1546-
(KI = getAsanInterceptor()->getKernelInfo(hKernel))) {
1524+
if (getAsanInterceptor()->getOptions().DetectKernelArguments) {
1525+
auto KI = getAsanInterceptor()->getKernelInfo(hKernel);
15471526
std::scoped_lock<ur_shared_mutex> Guard(KI->Mutex);
15481527
KI->PointerArgs[argIndex] = {pArgValue, GetCurrentBacktrace()};
15491528
}

source/loader/layers/sanitizer/asan/asan_interceptor.cpp

+33-18
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,13 @@ ur_result_t AsanInterceptor::insertKernel(ur_kernel_handle_t Kernel) {
644644
if (m_KernelMap.find(Kernel) != m_KernelMap.end()) {
645645
return UR_RESULT_SUCCESS;
646646
}
647-
m_KernelMap.emplace(Kernel, std::make_shared<KernelInfo>(Kernel));
647+
648+
auto hProgram = GetProgram(Kernel);
649+
auto PI = getAsanInterceptor()->getProgramInfo(hProgram);
650+
bool IsInstrumented = PI->isKernelInstrumented(Kernel);
651+
652+
m_KernelMap.emplace(Kernel,
653+
std::make_shared<KernelInfo>(Kernel, IsInstrumented));
648654
return UR_RESULT_SUCCESS;
649655
}
650656

@@ -685,9 +691,19 @@ ur_result_t AsanInterceptor::prepareLaunch(
685691
std::shared_ptr<ContextInfo> &ContextInfo,
686692
std::shared_ptr<DeviceInfo> &DeviceInfo, ur_queue_handle_t Queue,
687693
ur_kernel_handle_t Kernel, LaunchInfo &LaunchInfo) {
688-
689694
auto KernelInfo = getKernelInfo(Kernel);
690-
assert(KernelInfo && "Kernel should be instrumented");
695+
696+
auto ArgNums = GetKernelNumArgs(Kernel);
697+
auto LocalMemoryUsage =
698+
GetKernelLocalMemorySize(Kernel, DeviceInfo->Handle);
699+
auto PrivateMemoryUsage =
700+
GetKernelPrivateMemorySize(Kernel, DeviceInfo->Handle);
701+
702+
getContext()->logger.info(
703+
"KernelInfo {} (Name={}, ArgNums={}, IsInstrumented={}, "
704+
"LocalMemory={}, PrivateMemory={})",
705+
(void *)Kernel, GetKernelName(Kernel), ArgNums,
706+
KernelInfo->IsInstrumented, LocalMemoryUsage, PrivateMemoryUsage);
691707

692708
// Validate pointer arguments
693709
if (getOptions().DetectKernelArguments) {
@@ -719,11 +735,17 @@ ur_result_t AsanInterceptor::prepareLaunch(
719735
}
720736
}
721737

722-
auto ArgNums = GetKernelNumArgs(Kernel);
738+
if (!KernelInfo->IsInstrumented) {
739+
return UR_RESULT_SUCCESS;
740+
}
741+
723742
// We must prepare all kernel args before call
724743
// urKernelGetSuggestedLocalWorkSize, otherwise the call will fail on
725744
// CPU device.
726-
if (ArgNums) {
745+
{
746+
assert(ArgNums >= 1 &&
747+
"Sanitized Kernel should have at least one argument");
748+
727749
ur_result_t URes = getContext()->urDdiTable.Kernel.pfnSetArgPointer(
728750
Kernel, ArgNums - 1, nullptr, LaunchInfo.Data.getDevicePtr());
729751
if (URes != UR_RESULT_SUCCESS) {
@@ -763,15 +785,6 @@ ur_result_t AsanInterceptor::prepareLaunch(
763785
LaunchInfo.Data.Host.DeviceTy = DeviceInfo->Type;
764786
LaunchInfo.Data.Host.Debug = getOptions().Debug ? 1 : 0;
765787

766-
auto LocalMemoryUsage =
767-
GetKernelLocalMemorySize(Kernel, DeviceInfo->Handle);
768-
auto PrivateMemoryUsage =
769-
GetKernelPrivateMemorySize(Kernel, DeviceInfo->Handle);
770-
771-
getContext()->logger.info(
772-
"KernelInfo {} (LocalMemory={}, PrivateMemory={})", (void *)Kernel,
773-
LocalMemoryUsage, PrivateMemoryUsage);
774-
775788
// Write shadow memory offset for local memory
776789
if (getOptions().DetectLocals) {
777790
if (DeviceInfo->Shadow->AllocLocalShadow(
@@ -831,10 +844,12 @@ ur_result_t AsanInterceptor::prepareLaunch(
831844
// sync asan runtime data to device side
832845
UR_CALL(LaunchInfo.Data.syncToDevice(Queue));
833846

834-
getContext()->logger.debug("launch_info {} (numLocalArgs={}, localArgs={})",
835-
(void *)LaunchInfo.Data.getDevicePtr(),
836-
LaunchInfo.Data.Host.NumLocalArgs,
837-
(void *)LaunchInfo.Data.Host.LocalArgs);
847+
getContext()->logger.info(
848+
"LaunchInfo {} (device={}, debug={}, numLocalArgs={}, localArgs={})",
849+
(void *)LaunchInfo.Data.getDevicePtr(),
850+
ToString(LaunchInfo.Data.Host.DeviceTy), LaunchInfo.Data.Host.Debug,
851+
LaunchInfo.Data.Host.NumLocalArgs,
852+
(void *)LaunchInfo.Data.Host.LocalArgs);
838853

839854
return UR_RESULT_SUCCESS;
840855
}

source/loader/layers/sanitizer/asan/asan_interceptor.hpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ struct KernelInfo {
8585
ur_kernel_handle_t Handle;
8686
std::atomic<int32_t> RefCount = 1;
8787

88+
// sanitized kernel
89+
bool IsInstrumented = false;
90+
8891
// lock this mutex if following fields are accessed
8992
ur_shared_mutex Mutex;
9093
std::unordered_map<uint32_t, std::shared_ptr<MemBuffer>> BufferArgs;
@@ -94,7 +97,8 @@ struct KernelInfo {
9497
// Need preserve the order of local arguments
9598
std::map<uint32_t, LocalArgsInfo> LocalArgs;
9699

97-
explicit KernelInfo(ur_kernel_handle_t Kernel) : Handle(Kernel) {
100+
explicit KernelInfo(ur_kernel_handle_t Kernel, bool IsInstrumented)
101+
: Handle(Kernel), IsInstrumented(IsInstrumented) {
98102
[[maybe_unused]] auto Result =
99103
getContext()->urDdiTable.Kernel.pfnRetain(Kernel);
100104
assert(Result == UR_RESULT_SUCCESS);
@@ -348,10 +352,8 @@ class AsanInterceptor {
348352

349353
std::shared_ptr<KernelInfo> getKernelInfo(ur_kernel_handle_t Kernel) {
350354
std::shared_lock<ur_shared_mutex> Guard(m_KernelMapMutex);
351-
if (m_KernelMap.find(Kernel) != m_KernelMap.end()) {
352-
return m_KernelMap[Kernel];
353-
}
354-
return nullptr;
355+
assert(m_KernelMap.find(Kernel) != m_KernelMap.end());
356+
return m_KernelMap[Kernel];
355357
}
356358

357359
const AsanOptions &getOptions() { return m_Options; }

source/loader/layers/sanitizer/asan/asan_libdevice.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ struct AsanRuntimeData {
6666
uint32_t Debug = 0;
6767

6868
int ReportFlag = 0;
69-
AsanErrorReport Report[ASAN_MAX_NUM_REPORTS];
69+
AsanErrorReport Report[ASAN_MAX_NUM_REPORTS] = {};
7070
};
7171

7272
constexpr unsigned ASAN_SHADOW_SCALE = 4;

0 commit comments

Comments
 (0)