diff --git a/devops/compat_ci_exclude.sycl-rel-6_3 b/devops/compat_ci_exclude.sycl-rel-6_3 index de9fd5a1e10b8..9162fce15db7b 100644 --- a/devops/compat_ci_exclude.sycl-rel-6_3 +++ b/devops/compat_ci_exclude.sycl-rel-6_3 @@ -22,3 +22,9 @@ NonUniformGroups/opportunistic_group.cpp # toolchain used to build the test, not the toolchain we're using SYCL RT from # to run against pre-built E2E binaries. Basic/device_config_file_consistency.cpp + +# The ABI compatibility is unimportant to device sanitizer since the user must +# re-build their code if they want to test their code with device sanitizer. +AddressSanitizer/* +MemorySanitizer/* +ThreadSanitizer/* diff --git a/libdevice/include/sanitizer_defs.hpp b/libdevice/include/sanitizer_defs.hpp index 8f4e0b06c2afd..9e8bab0304668 100644 --- a/libdevice/include/sanitizer_defs.hpp +++ b/libdevice/include/sanitizer_defs.hpp @@ -61,6 +61,9 @@ extern SYCL_EXTERNAL __attribute__((convergent)) void __spirv_ControlBarrier(int32_t Execution, int32_t Memory, int32_t Semantics) noexcept; +template +extern SYCL_EXTERNAL T __spirv_SpecConstant(int ID, T default_value) noexcept; + extern "C" SYCL_EXTERNAL void __devicelib_exit(); #endif // __SPIR__ || __SPIRV__ diff --git a/libdevice/include/sanitizer_utils.hpp b/libdevice/include/sanitizer_utils.hpp index 9af22da36c62e..bbc84f4553fa4 100644 --- a/libdevice/include/sanitizer_utils.hpp +++ b/libdevice/include/sanitizer_utils.hpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #pragma once +#include "sanitizer_common/sanitizer_libdevice.hpp" #include "sanitizer_defs.hpp" -#include "spirv_vars.h" #if defined(__SPIR__) || defined(__SPIRV__) @@ -49,6 +49,11 @@ inline __SYCL_PRIVATE__ void *ToPrivate(void *ptr) { return __spirv_GenericCastToPtrExplicit_ToPrivate(ptr, 7); } +inline DeviceType GetDeviceTy() { + return static_cast( + __spirv_SpecConstant(SPEC_CONSTANT_DEVICE_TYPE_ID, 0)); +} + template T Memset(T ptr, int value, size_t size) { for (size_t i = 0; i < size; i++) { ptr[i] = value; diff --git a/libdevice/sanitizer/asan_rtl.cpp b/libdevice/sanitizer/asan_rtl.cpp index 087a67bf39649..076cd61df578f 100644 --- a/libdevice/sanitizer/asan_rtl.cpp +++ b/libdevice/sanitizer/asan_rtl.cpp @@ -264,16 +264,15 @@ inline uptr MemToShadow(uptr addr, uint32_t as, #elif defined(__LIBDEVICE_DG2__) shadow_ptr = MemToShadow_DG2(addr, as, debug); #else - auto launch_info = (__SYCL_GLOBAL__ const AsanRuntimeData *)__AsanLaunchInfo; - if (launch_info->DeviceTy == DeviceType::CPU) { + if (GetDeviceTy() == DeviceType::CPU) { shadow_ptr = MemToShadow_CPU(addr); - } else if (launch_info->DeviceTy == DeviceType::GPU_PVC) { + } else if (GetDeviceTy() == DeviceType::GPU_PVC) { shadow_ptr = MemToShadow_PVC(addr, as, debug); - } else if (launch_info->DeviceTy == DeviceType::GPU_DG2) { + } else if (GetDeviceTy() == DeviceType::GPU_DG2) { shadow_ptr = MemToShadow_DG2(addr, as, debug); } else { ASAN_DEBUG(__spirv_ocl_printf(__asan_print_unsupport_device_type, - (int)launch_info->DeviceTy)); + (int)GetDeviceTy())); ReportUnknownDevice(debug); return 0; } @@ -889,8 +888,7 @@ DEVICE_EXTERN_C_NOINLINE void __asan_set_shadow_private(uptr shadow, uptr size, static __SYCL_CONSTANT__ const char __asan_print_private_base[] = "[kernel] set_private_base: %llu -> %p\n"; -DEVICE_EXTERN_C_NOINLINE void -__asan_set_private_base(__SYCL_PRIVATE__ void *ptr) { +inline void SetPrivateBaseImpl(__SYCL_PRIVATE__ void *ptr) { auto launch_info = (__SYCL_GLOBAL__ const AsanRuntimeData *)__AsanLaunchInfo; const size_t sid = SubGroupLinearId(); if (!launch_info || sid >= ASAN_MAX_SG_PRIVATE || @@ -904,4 +902,17 @@ __asan_set_private_base(__SYCL_PRIVATE__ void *ptr) { SubGroupBarrier(); } +DEVICE_EXTERN_C_NOINLINE void +__asan_set_private_base(__SYCL_PRIVATE__ void *ptr) { +#if defined(__LIBDEVICE_CPU__) + return; +#elif defined(__LIBDEVICE_DG2__) || defined(__LIBDEVICE_PVC__) + SetPrivateBaseImpl(ptr); +#else + if (GetDeviceTy() == DeviceType::CPU) + return; + SetPrivateBaseImpl(ptr); +#endif +} + #endif // __SPIR__ || __SPIRV__ diff --git a/libdevice/sanitizer/msan_rtl.cpp b/libdevice/sanitizer/msan_rtl.cpp index 87d57fc6950c5..9be95fafc27a3 100644 --- a/libdevice/sanitizer/msan_rtl.cpp +++ b/libdevice/sanitizer/msan_rtl.cpp @@ -212,16 +212,16 @@ inline uptr MemToShadow(uptr addr, uint32_t as) { #elif defined(__LIBDEVICE_CPU__) shadow_ptr = MemToShadow_CPU(addr); #else - if (LIKELY(GetMsanLaunchInfo->DeviceTy == DeviceType::CPU)) { + if (GetDeviceTy() == DeviceType::CPU) { shadow_ptr = MemToShadow_CPU(addr); - } else if (GetMsanLaunchInfo->DeviceTy == DeviceType::GPU_PVC) { + } else if (GetDeviceTy() == DeviceType::GPU_PVC) { shadow_ptr = MemToShadow_PVC(addr, as); - } else if (GetMsanLaunchInfo->DeviceTy == DeviceType::GPU_DG2) { + } else if (GetDeviceTy() == DeviceType::GPU_DG2) { shadow_ptr = MemToShadow_DG2(addr, as); } else { shadow_ptr = GetMsanLaunchInfo->CleanShadow; - MSAN_DEBUG(__spirv_ocl_printf(__msan_print_unsupport_device_type, - GetMsanLaunchInfo->DeviceTy)); + MSAN_DEBUG( + __spirv_ocl_printf(__msan_print_unsupport_device_type, GetDeviceTy())); } #endif @@ -269,17 +269,17 @@ inline uptr MemToOrigin(uptr addr, uint32_t as) { #elif defined(__LIBDEVICE_CPU__) origin_ptr = MemToOrigin_CPU(addr); #else - if (LIKELY(GetMsanLaunchInfo->DeviceTy == DeviceType::CPU)) { + if (GetDeviceTy() == DeviceType::CPU) { origin_ptr = MemToOrigin_CPU(aligned_addr); - } else if (GetMsanLaunchInfo->DeviceTy == DeviceType::GPU_PVC) { + } else if (GetDeviceTy() == DeviceType::GPU_PVC) { origin_ptr = MemToOrigin_PVC(aligned_addr, as); - } else if (GetMsanLaunchInfo->DeviceTy == DeviceType::GPU_DG2) { + } else if (GetDeviceTy() == DeviceType::GPU_DG2) { origin_ptr = MemToOrigin_DG2(aligned_addr, as); } else { // Return clean shadow (0s) by default origin_ptr = GetMsanLaunchInfo->CleanShadow; - MSAN_DEBUG(__spirv_ocl_printf(__msan_print_unsupport_device_type, - GetMsanLaunchInfo->DeviceTy)); + MSAN_DEBUG( + __spirv_ocl_printf(__msan_print_unsupport_device_type, GetDeviceTy())); } #endif @@ -737,8 +737,7 @@ DEVICE_EXTERN_C_NOINLINE void __msan_unpoison_shadow(uptr ptr, uint32_t as, static __SYCL_CONSTANT__ const char __msan_print_private_base[] = "[kernel] __msan_set_private_base(sid=%llu): %p\n"; -DEVICE_EXTERN_C_NOINLINE void -__msan_set_private_base(__SYCL_PRIVATE__ void *ptr) { +inline void SetPrivateBaseImpl(__SYCL_PRIVATE__ void *ptr) { const size_t sid = SubGroupLinearId(); if (!GetMsanLaunchInfo || sid >= MSAN_MAX_SG_PRIVATE || GetMsanLaunchInfo->PrivateShadowOffset == 0 || @@ -752,6 +751,19 @@ __msan_set_private_base(__SYCL_PRIVATE__ void *ptr) { SubGroupBarrier(); } +DEVICE_EXTERN_C_NOINLINE void +__msan_set_private_base(__SYCL_PRIVATE__ void *ptr) { +#if defined(__LIBDEVICE_CPU__) + return; +#elif defined(__LIBDEVICE_DG2__) || defined(__LIBDEVICE_PVC__) + SetPrivateBaseImpl(ptr); +#else + if (GetDeviceTy() == DeviceType::CPU) + return; + SetPrivateBaseImpl(ptr); +#endif +} + static __SYCL_CONSTANT__ const char __msan_print_strided_copy_unsupport_type[] = "[kernel] __msan_unpoison_strided_copy: unsupported type(%d)\n"; diff --git a/libdevice/sanitizer/tsan_rtl.cpp b/libdevice/sanitizer/tsan_rtl.cpp index 704ca581ea4bb..f44c529210f0e 100644 --- a/libdevice/sanitizer/tsan_rtl.cpp +++ b/libdevice/sanitizer/tsan_rtl.cpp @@ -127,13 +127,13 @@ inline __SYCL_GLOBAL__ RawShadow *MemToShadow(uptr addr, uint32_t as) { #elif defined(__LIBDEVICE_PVC__) shadow_ptr = MemToShadow_PVC(addr, as); #else - if (TsanLaunchInfo->DeviceTy == DeviceType::CPU) { + if (GetDeviceTy() == DeviceType::CPU) { shadow_ptr = MemToShadow_CPU(addr, as); - } else if (TsanLaunchInfo->DeviceTy == DeviceType::GPU_PVC) { + } else if (GetDeviceTy() == DeviceType::GPU_PVC) { shadow_ptr = MemToShadow_PVC(addr, as); } else { TSAN_DEBUG(__spirv_ocl_printf(__tsan_print_unsupport_device_type, - (int)TsanLaunchInfo->DeviceTy)); + (int)GetDeviceTy())); return nullptr; } #endif @@ -186,10 +186,16 @@ inline void DoReportRace(__SYCL_GLOBAL__ RawShadow *s, AccessType type, return; } - if (as == ADDRESS_SPACE_GENERIC && - TsanLaunchInfo->DeviceTy != DeviceType::CPU) { +#if defined(__LIBDEVICE_CPU__) +#elif defined(__LIBDEVICE_DG2__) || defined(__LIBDEVICE_PVC__) + if (as == ADDRESS_SPACE_GENERIC) { ConvertGenericPointer(addr, as); } +#else + if (as == ADDRESS_SPACE_GENERIC && GetDeviceTy() != DeviceType::CPU) { + ConvertGenericPointer(addr, as); + } +#endif // Check if current address already being recorded before. for (uint32_t i = 0; i < TsanLaunchInfo->RecordedReportCount; i++) { @@ -467,7 +473,7 @@ DEVICE_EXTERN_C_NOINLINE void __tsan_cleanup_private(uptr addr, size_t size) { #elif defined(__LIBDEVICE_PVC__) return; #else - if (TsanLaunchInfo->DeviceTy != DeviceType::CPU) + if (GetDeviceTy() != DeviceType::CPU) return; __tsan_cleanup_private_cpu_impl(addr, size); diff --git a/unified-runtime/source/loader/layers/sanitizer/asan/asan_interceptor.cpp b/unified-runtime/source/loader/layers/sanitizer/asan/asan_interceptor.cpp index 4ae3b1795b6ae..f31642369cac3 100644 --- a/unified-runtime/source/loader/layers/sanitizer/asan/asan_interceptor.cpp +++ b/unified-runtime/source/loader/layers/sanitizer/asan/asan_interceptor.cpp @@ -643,6 +643,19 @@ ur_result_t AsanInterceptor::insertProgram(ur_program_handle_t Program) { if (m_ProgramMap.find(Program) != m_ProgramMap.end()) { return UR_RESULT_SUCCESS; } + auto CI = getContextInfo(GetContext(Program)); + auto DI = getDeviceInfo(CI->DeviceList[0]); + ur_specialization_constant_info_t SpecConstantInfo{ + SPEC_CONSTANT_DEVICE_TYPE_ID, sizeof(DeviceType), &DI->Type}; + ur_result_t URes = + getContext()->urDdiTable.Program.pfnSetSpecializationConstants( + Program, 1, &SpecConstantInfo); + if (URes != UR_RESULT_SUCCESS) { + UR_LOG_L(getContext()->logger, DEBUG, + "Set specilization constant for device type failed: {}, the " + "program may not be sanitized or is created from binary.", + URes); + } m_ProgramMap.emplace(Program, std::make_shared(Program)); return UR_RESULT_SUCCESS; } @@ -812,7 +825,6 @@ ur_result_t AsanInterceptor::prepareLaunch( // Prepare asan runtime data LaunchInfo.Data.Host.GlobalShadowOffset = DeviceInfo->Shadow->ShadowBegin; LaunchInfo.Data.Host.GlobalShadowOffsetEnd = DeviceInfo->Shadow->ShadowEnd; - LaunchInfo.Data.Host.DeviceTy = DeviceInfo->Type; LaunchInfo.Data.Host.Debug = getContext()->Options.Debug ? 1 : 0; // Write shadow memory offset for local memory @@ -874,16 +886,14 @@ ur_result_t AsanInterceptor::prepareLaunch( UR_LOG_L(getContext()->logger, INFO, "LaunchInfo {} (GlobalShadow={}, LocalShadow={}, PrivateBase={}, " - "PrivateShadow={}, LocalArgs={}, NumLocalArgs={}, " - "Device={}, Debug={})", + "PrivateShadow={}, LocalArgs={}, NumLocalArgs={}, Debug={})", (void *)LaunchInfo.Data.getDevicePtr(), (void *)LaunchInfo.Data.Host.GlobalShadowOffset, (void *)LaunchInfo.Data.Host.LocalShadowOffset, (void *)LaunchInfo.Data.Host.PrivateBase, (void *)LaunchInfo.Data.Host.PrivateShadowOffset, (void *)LaunchInfo.Data.Host.LocalArgs, - LaunchInfo.Data.Host.NumLocalArgs, - ToString(LaunchInfo.Data.Host.DeviceTy), LaunchInfo.Data.Host.Debug); + LaunchInfo.Data.Host.NumLocalArgs, LaunchInfo.Data.Host.Debug); return UR_RESULT_SUCCESS; } diff --git a/unified-runtime/source/loader/layers/sanitizer/asan/asan_libdevice.hpp b/unified-runtime/source/loader/layers/sanitizer/asan/asan_libdevice.hpp index d076f6537f9dd..c3e05479915ca 100644 --- a/unified-runtime/source/loader/layers/sanitizer/asan/asan_libdevice.hpp +++ b/unified-runtime/source/loader/layers/sanitizer/asan/asan_libdevice.hpp @@ -69,7 +69,6 @@ struct AsanRuntimeData { LocalArgsInfo *LocalArgs = nullptr; // Ordered by ArgIndex uint32_t NumLocalArgs = 0; - DeviceType DeviceTy = DeviceType::UNKNOWN; uint32_t Debug = 0; int ReportFlag = 0; diff --git a/unified-runtime/source/loader/layers/sanitizer/msan/msan_interceptor.cpp b/unified-runtime/source/loader/layers/sanitizer/msan/msan_interceptor.cpp index de6c9c241cd76..4838a1a58e22e 100644 --- a/unified-runtime/source/loader/layers/sanitizer/msan/msan_interceptor.cpp +++ b/unified-runtime/source/loader/layers/sanitizer/msan/msan_interceptor.cpp @@ -384,6 +384,19 @@ ur_result_t MsanInterceptor::insertProgram(ur_program_handle_t Program) { if (m_ProgramMap.find(Program) != m_ProgramMap.end()) { return UR_RESULT_SUCCESS; } + auto CI = getContextInfo(GetContext(Program)); + auto DI = getDeviceInfo(CI->DeviceList[0]); + ur_specialization_constant_info_t SpecConstantInfo{ + SPEC_CONSTANT_DEVICE_TYPE_ID, sizeof(DeviceType), &DI->Type}; + ur_result_t URes = + getContext()->urDdiTable.Program.pfnSetSpecializationConstants( + Program, 1, &SpecConstantInfo); + if (URes != UR_RESULT_SUCCESS) { + UR_LOG_L(getContext()->logger, DEBUG, + "Set specilization constant for device type failed: {}, the " + "program may not be sanitized or is created from binary.", + URes); + } m_ProgramMap.emplace(Program, std::make_shared(Program)); return UR_RESULT_SUCCESS; } @@ -492,7 +505,6 @@ ur_result_t MsanInterceptor::prepareLaunch( LaunchInfo.Data.Host.GlobalShadowOffset = DeviceInfo->Shadow->ShadowBegin; LaunchInfo.Data.Host.GlobalShadowOffsetEnd = DeviceInfo->Shadow->ShadowEnd; - LaunchInfo.Data.Host.DeviceTy = DeviceInfo->Type; LaunchInfo.Data.Host.Debug = getContext()->Options.Debug ? 1 : 0; LaunchInfo.Data.Host.IsRecover = getContext()->Options.Recover ? 1 : 0; @@ -599,7 +611,7 @@ ur_result_t MsanInterceptor::prepareLaunch( UR_LOG_L(getContext()->logger, INFO, "LaunchInfo {} (GlobalShadow={}, LocalShadow={}, PrivateBase={}, " "PrivateShadow={}, CleanShadow={}, LocalArgs={}, NumLocalArgs={}, " - "Device={}, Debug={})", + "Debug={})", (void *)LaunchInfo.Data.getDevicePtr(), (void *)LaunchInfo.Data.Host.GlobalShadowOffset, (void *)LaunchInfo.Data.Host.LocalShadowOffset, @@ -607,8 +619,7 @@ ur_result_t MsanInterceptor::prepareLaunch( (void *)LaunchInfo.Data.Host.PrivateShadowOffset, (void *)LaunchInfo.Data.Host.CleanShadow, (void *)LaunchInfo.Data.Host.LocalArgs, - LaunchInfo.Data.Host.NumLocalArgs, - ToString(LaunchInfo.Data.Host.DeviceTy), LaunchInfo.Data.Host.Debug); + LaunchInfo.Data.Host.NumLocalArgs, LaunchInfo.Data.Host.Debug); ur_result_t URes = getContext()->urDdiTable.Enqueue.pfnDeviceGlobalVariableWrite( diff --git a/unified-runtime/source/loader/layers/sanitizer/msan/msan_libdevice.hpp b/unified-runtime/source/loader/layers/sanitizer/msan/msan_libdevice.hpp index d57d0c8553446..d618629a3b9b1 100644 --- a/unified-runtime/source/loader/layers/sanitizer/msan/msan_libdevice.hpp +++ b/unified-runtime/source/loader/layers/sanitizer/msan/msan_libdevice.hpp @@ -64,7 +64,6 @@ struct MsanRuntimeData { uintptr_t CleanShadow = 0; - DeviceType DeviceTy = DeviceType::UNKNOWN; uint32_t Debug = 0; uint32_t IsRecover = 0; diff --git a/unified-runtime/source/loader/layers/sanitizer/sanitizer_common/sanitizer_libdevice.hpp b/unified-runtime/source/loader/layers/sanitizer/sanitizer_common/sanitizer_libdevice.hpp index f47ae10606d88..b0f447711cb5f 100644 --- a/unified-runtime/source/loader/layers/sanitizer/sanitizer_common/sanitizer_libdevice.hpp +++ b/unified-runtime/source/loader/layers/sanitizer/sanitizer_common/sanitizer_libdevice.hpp @@ -21,6 +21,9 @@ namespace ur_sanitizer_layer { enum class DeviceType : uint32_t { UNKNOWN = 0, CPU, GPU_PVC, GPU_DG2 }; +// Try to use a larger ID number to avoid conflict with user ID. +#define SPEC_CONSTANT_DEVICE_TYPE_ID (INT32_MAX - 1) + inline const char *ToString(DeviceType Type) { switch (Type) { case DeviceType::UNKNOWN: diff --git a/unified-runtime/source/loader/layers/sanitizer/tsan/tsan_interceptor.cpp b/unified-runtime/source/loader/layers/sanitizer/tsan/tsan_interceptor.cpp index 3f9248489f52b..0641849faa214 100644 --- a/unified-runtime/source/loader/layers/sanitizer/tsan/tsan_interceptor.cpp +++ b/unified-runtime/source/loader/layers/sanitizer/tsan/tsan_interceptor.cpp @@ -307,6 +307,19 @@ ur_result_t TsanInterceptor::insertProgram(ur_program_handle_t Program) { if (m_ProgramMap.find(Program) != m_ProgramMap.end()) { return UR_RESULT_SUCCESS; } + auto CI = getContextInfo(GetContext(Program)); + auto DI = getDeviceInfo(CI->DeviceList[0]); + ur_specialization_constant_info_t SpecConstantInfo{ + SPEC_CONSTANT_DEVICE_TYPE_ID, sizeof(DeviceType), &DI->Type}; + ur_result_t URes = + getContext()->urDdiTable.Program.pfnSetSpecializationConstants( + Program, 1, &SpecConstantInfo); + if (URes != UR_RESULT_SUCCESS) { + UR_LOG_L(getContext()->logger, DEBUG, + "Set specilization constant for device type failed: {}, the " + "program may not be sanitized or is created from binary.", + URes); + } m_ProgramMap.emplace(Program, Program); return UR_RESULT_SUCCESS; } @@ -425,7 +438,6 @@ ur_result_t TsanInterceptor::prepareLaunch(std::shared_ptr &, // Prepare launch info data LaunchInfo.Data.Host.GlobalShadowOffset = DI->Shadow->ShadowBegin; LaunchInfo.Data.Host.GlobalShadowOffsetEnd = DI->Shadow->ShadowEnd; - LaunchInfo.Data.Host.DeviceTy = DI->Type; LaunchInfo.Data.Host.Debug = getContext()->Options.Debug ? 1 : 0; const size_t *LocalWorkSize = LaunchInfo.LocalWorkSize.data(); diff --git a/unified-runtime/source/loader/layers/sanitizer/tsan/tsan_libdevice.hpp b/unified-runtime/source/loader/layers/sanitizer/tsan/tsan_libdevice.hpp index bacf4fda75179..81da9d31a4d91 100644 --- a/unified-runtime/source/loader/layers/sanitizer/tsan/tsan_libdevice.hpp +++ b/unified-runtime/source/loader/layers/sanitizer/tsan/tsan_libdevice.hpp @@ -99,8 +99,6 @@ struct TsanRuntimeData { // The last one is to record global state VectorClock Clock[kThreadSlotCount + 1]; - DeviceType DeviceTy = DeviceType::UNKNOWN; - uint32_t Debug = 0; int Lock = 0;