Skip to content

Commit

Permalink
[DeviceSanitizer] Support CPU Device & Static Local Memory (#12248)
Browse files Browse the repository at this point in the history
UR: oneapi-src/unified-runtime#1210

---------

Co-authored-by: Maosu Zhao <[email protected]>
  • Loading branch information
AllanZyne and zhaomaosu authored Feb 5, 2024
1 parent 153ccbe commit f331ba2
Show file tree
Hide file tree
Showing 19 changed files with 1,304 additions and 36 deletions.
21 changes: 21 additions & 0 deletions libdevice/atomic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ __spirv_AtomicCompareExchange(int SPIR_GLOBAL *, __spv::Scope::Flag,
__spv::MemorySemanticsMask::Flag,
__spv::MemorySemanticsMask::Flag, int, int);

extern DEVICE_EXTERNAL int
__spirv_AtomicCompareExchange(int *, __spv::Scope::Flag,
__spv::MemorySemanticsMask::Flag,
__spv::MemorySemanticsMask::Flag, int, int);

extern DEVICE_EXTERNAL int __spirv_AtomicLoad(const int SPIR_GLOBAL *,
__spv::Scope::Flag,
__spv::MemorySemanticsMask::Flag);
Expand All @@ -70,6 +75,10 @@ extern DEVICE_EXTERNAL void
__spirv_AtomicStore(int SPIR_GLOBAL *, __spv::Scope::Flag,
__spv::MemorySemanticsMask::Flag, int);

extern DEVICE_EXTERNAL void
__spirv_AtomicStore(int *, __spv::Scope::Flag, __spv::MemorySemanticsMask::Flag,
int);

/// Atomically set the value in *Ptr with Desired if and only if it is Expected
/// Return the value which already was in *Ptr
static inline int atomicCompareAndSet(SPIR_GLOBAL int *Ptr, int Desired,
Expand All @@ -80,6 +89,13 @@ static inline int atomicCompareAndSet(SPIR_GLOBAL int *Ptr, int Desired,
__spv::MemorySemanticsMask::SequentiallyConsistent, Desired, Expected);
}

static inline int atomicCompareAndSet(int *Ptr, int Desired, int Expected) {
return __spirv_AtomicCompareExchange(
Ptr, __spv::Scope::Device,
__spv::MemorySemanticsMask::SequentiallyConsistent,
__spv::MemorySemanticsMask::SequentiallyConsistent, Desired, Expected);
}

static inline int atomicLoad(SPIR_GLOBAL int *Ptr) {
return __spirv_AtomicLoad(Ptr, __spv::Scope::Device,
__spv::MemorySemanticsMask::SequentiallyConsistent);
Expand All @@ -90,4 +106,9 @@ static inline void atomicStore(SPIR_GLOBAL int *Ptr, int V) {
__spv::MemorySemanticsMask::SequentiallyConsistent, V);
}

static inline void atomicStore(int *Ptr, int V) {
__spirv_AtomicStore(Ptr, __spv::Scope::Device,
__spv::MemorySemanticsMask::SequentiallyConsistent, V);
}

#endif // __SPIR__
6 changes: 3 additions & 3 deletions libdevice/cmake/modules/SYCLLibdevice.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ set(imf_obj_deps device_imf.hpp imf_half.hpp imf_bf16.hpp imf_rounding_op.hpp im
set(itt_obj_deps device_itt.h spirv_vars.h device.h sycl-compiler)
set(bfloat16_obj_deps sycl-headers sycl-compiler)
if (NOT MSVC)
set(sanitizer_obj_deps device.h sycl-compiler)
set(sanitizer_obj_deps device.h atomic.hpp spirv_vars.h include/sanitizer_device_utils.hpp include/spir_global_var.hpp sycl-compiler)
endif()

add_devicelib_obj(libsycl-itt-stubs SRC itt_stubs.cpp DEP ${itt_obj_deps})
Expand All @@ -126,9 +126,9 @@ add_devicelib_obj(libsycl-imf-fp64 SRC imf_wrapper_fp64.cpp DEP ${imf_obj_deps})
add_devicelib_obj(libsycl-imf-bf16 SRC imf_wrapper_bf16.cpp DEP ${imf_obj_deps})
add_devicelib_obj(libsycl-bfloat16 SRC bfloat16_wrapper.cpp DEP ${cmath_obj_deps} )
if(MSVC)
add_devicelib_obj(libsycl-msvc-math SRC msvc_math.cpp DEP ${cmath_obj_deps})
add_devicelib_obj(libsycl-msvc-math SRC msvc_math.cpp DEP ${cmath_obj_deps})
else()
add_devicelib_obj(libsycl-sanitizer SRC sanitizer_utils.cpp DEP ${sanitizer_obj_deps})
add_devicelib_obj(libsycl-sanitizer SRC sanitizer_utils.cpp DEP ${sanitizer_obj_deps} EXTRA_ARGS -fno-sycl-instrument-device-code)
endif()

add_fallback_devicelib(libsycl-fallback-cassert SRC fallback-cassert.cpp DEP ${crt_obj_deps} EXTRA_ARGS -fno-sycl-instrument-device-code)
Expand Down
58 changes: 58 additions & 0 deletions libdevice/include/device-sanitizer-report.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//==-- device-sanitizer-report.hpp - Structure and declaration for assert
// support --==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#pragma once

// Treat this header as system one to workaround frontend's restriction
#pragma clang system_header

#include <cinttypes>

enum class DeviceSanitizerErrorType : int32_t {
UNKNOWN,
OUT_OF_BOUND,
MISALIGNED,
USE_AFTER_FREE,
OUT_OF_SHADOW_BOUND,
};

enum class DeviceSanitizerMemoryType : int32_t {
UNKNOWN,
USM_DEVICE,
USM_HOST,
USM_SHARED,
LOCAL,
PRIVATE,
MEM_BUFFER,
};

// NOTE Layout of this structure should be aligned with the one in
// sycl/include/sycl/detail/device_sanitizer_report.hpp
struct DeviceSanitizerReport {
int Flag = 0;

char File[256 + 1] = "";
char Func[256 + 1] = "";

int32_t Line = 0;

uint64_t GID0 = 0;
uint64_t GID1 = 0;
uint64_t GID2 = 0;

uint64_t LID0 = 0;
uint64_t LID1 = 0;
uint64_t LID2 = 0;

bool IsWrite = false;
uint32_t AccessSize = 0;
DeviceSanitizerMemoryType MemoryType = DeviceSanitizerMemoryType::UNKNOWN;
DeviceSanitizerErrorType ErrorType = DeviceSanitizerErrorType::UNKNOWN;

bool IsRecover = false;
};
49 changes: 49 additions & 0 deletions libdevice/include/sanitizer_device_utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//==-- sanitizer_device_utils.hpp - Declaration for sanitizer global var ---==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#pragma once

#include "spir_global_var.hpp"
#include <cstdint>

// Treat this header as system one to workaround frontend's restriction
#pragma clang system_header

template <typename T>
class
#ifdef __SYCL_DEVICE_ONLY__
[[__sycl_detail__::global_variable_allowed, __sycl_detail__::device_global,
__sycl_detail__::add_ir_attributes_global_variable(
"sycl-device-global-size", "sycl-device-image-scope", sizeof(T),
nullptr)]]
#endif
DeviceGlobal {
public:
DeviceGlobal() = default;
DeviceGlobal(const DeviceGlobal &) = delete;
DeviceGlobal(const DeviceGlobal &&) = delete;
DeviceGlobal &operator=(const DeviceGlobal &) = delete;
DeviceGlobal &operator=(const DeviceGlobal &&) = delete;

DeviceGlobal &operator=(const T newValue) noexcept {
val = newValue;
return *this;
}

operator T &() noexcept { return val; }

operator const T &() const noexcept { return val; }

T &get() noexcept { return val; }

const T &get() const noexcept { return val; }

private:
T val;
};

enum DeviceType : uintptr_t { UNKNOWN, CPU, GPU_PVC, GPU_DG2 };
26 changes: 26 additions & 0 deletions libdevice/include/spir_global_var.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//==- spir_global_var.hpp - Declaration for device global variable support -==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#pragma once

// Treat this header as system one to workaround frontend's restriction
#pragma clang system_header

#ifndef SPIR_GLOBAL_VAR
#ifdef __SYCL_DEVICE_ONLY__
#define SPIR_GLOBAL_VAR __attribute__((sycl_global_var))
#else
#warning "SPIR_GLOBAL_VAR not defined in host mode. Defining as empty macro."
#define SPIR_GLOBAL_VAR
#endif
#endif

#define __SYCL_GLOBAL__ __attribute__((opencl_global))
#define __SYCL_LOCAL__ __attribute__((opencl_local))
#define __SYCL_PRIVATE__ __attribute__((opencl_private))
#define __SYCL_CONSTANT__ __attribute__((opencl_constant))
Loading

0 comments on commit f331ba2

Please sign in to comment.