Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding asan sanitizer support for hip #795

Open
wants to merge 28 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a7e72b3
adding asan sanitizer support for hip
kab163 Nov 23, 2022
f90a7af
Apply style updates
Nov 23, 2022
00e3f43
WIP adding a hip kernel sanitizer test
kab163 Dec 6, 2022
ac5cd62
Apply style updates
Dec 6, 2022
522a4a9
adding usage checkers to sanitizer test
kab163 Dec 7, 2022
3ac6a7c
Apply style updates
Dec 7, 2022
a4f007a
more updates to sanitizer test for error checking
kab163 Dec 7, 2022
a1c0180
merging...
kab163 Dec 7, 2022
8b9e194
Apply style updates
Dec 7, 2022
6617aba
adding hip define macros
kab163 Dec 7, 2022
4c17280
Apply style updates
Dec 7, 2022
5379807
getting rid of double pointer
kab163 Dec 8, 2022
4e4804f
updating sanitizer test
kab163 Dec 21, 2022
4b92502
Apply style updates
Dec 21, 2022
276f15b
Merge branch 'develop' of github.com:LLNL/Umpire into task/UM-1020-as…
kab163 Apr 3, 2023
986c5a1
Merge branch 'develop' of github.com:LLNL/Umpire into task/UM-1020-as…
kab163 Sep 18, 2023
3858c0f
Merge branch 'develop' of https://github.com/LLNL/Umpire into task/UM…
kab163 Dec 12, 2023
e9bf9f6
adding flag for hip asan
kab163 Jan 22, 2024
0232f2c
updates for rocm test
kab163 Jan 22, 2024
f154c08
had to update the test runner to handle new paramter
kab163 Jan 23, 2024
2019270
Merge branch 'develop' into task/UM-1020-asan-poisoning-for-hip
davidbeckingsale Jun 6, 2024
417b66d
Remove umpire namespace from fmt call
davidbeckingsale Jun 6, 2024
43f0875
Allow +tools+rocm in Umpire package
davidbeckingsale Jun 7, 2024
f76f5be
Add amdgpu_target for new memleak job
davidbeckingsale Jun 7, 2024
f2eb907
remove extra linker flags
davidbeckingsale Jun 7, 2024
1332301
Add xnack+ to target for memleak job
davidbeckingsale Jun 7, 2024
9022631
Increase allocation on tioga due to memleak job
adrienbernede Jun 10, 2024
c458f02
Merge branch 'develop' into task/UM-1020-asan-poisoning-for-hip
adrienbernede Jun 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitlab/custom-jobs-and-variables.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ variables:

# Tioga
# Arguments for top level allocation
TIOGA_SHARED_ALLOC: "--queue=pci --exclusive --time-limit=15m --nodes=1"
TIOGA_SHARED_ALLOC: "--queue=pci --exclusive --time-limit=60m --nodes=1"
# Arguments for job level allocation
TIOGA_JOB_ALLOC: "--nodes=1 --begin-time=+5s"
# Project specific variants for tioga
Expand Down
5 changes: 5 additions & 0 deletions .gitlab/jobs/tioga.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,8 @@ rocmcc_6_1_1_hip_openmp_device_alloc:
SPEC: "~shared +fortran +openmp +rocm +device_alloc tests=basic amdgpu_target=gfx90a %rocmcc@=6.1.1 ^[email protected]"
extends: .job_on_tioga

rocmcc_6_1_1_hip_memleak:
variables:
SPEC: "~shared +asan +sanitizer_tests +tools +rocm tests=basic amdgpu_target=gfx90a:xnack+ cxxflags==\"-fsanitize=address\" %[email protected] ^[email protected]"
ASAN_OPTIONS: "detect_leaks=1"
extends: .job_on_tioga
2 changes: 1 addition & 1 deletion scripts/radiuss-spack-configs
12 changes: 6 additions & 6 deletions src/umpire/util/memory_sanitizers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@

#if defined(__UMPIRE_USE_MEMORY_SANITIZER__)

#define UMPIRE_POISON_MEMORY_REGION(allocator, ptr, size) \
if (allocator->getPlatform() == umpire::Platform::host) { \
ASAN_POISON_MEMORY_REGION((ptr), (size)); \
#define UMPIRE_POISON_MEMORY_REGION(allocator, ptr, size) \
if (allocator->getPlatform() == umpire::Platform::host || allocator->getPlatform() == umpire::Platform::hip) { \
ASAN_POISON_MEMORY_REGION((ptr), (size)); \
}

#define UMPIRE_UNPOISON_MEMORY_REGION(allocator, ptr, size) \
if (allocator->getPlatform() == umpire::Platform::host) { \
ASAN_UNPOISON_MEMORY_REGION((ptr), (size)); \
#define UMPIRE_UNPOISON_MEMORY_REGION(allocator, ptr, size) \
if (allocator->getPlatform() == umpire::Platform::host || allocator->getPlatform() == umpire::Platform::hip) { \
ASAN_UNPOISON_MEMORY_REGION((ptr), (size)); \
}

#else // !defined(__UMPIRE_USE_MEMORY_SANITIZER__)
Expand Down
9 changes: 8 additions & 1 deletion tests/tools/sanitizers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@
#
# SPDX-License-Identifier: (MIT)
##############################################################################
set (sanitizer_depends umpire umpire_util)

if (UMPIRE_ENABLE_HIP)
set (sanitizer_depends
${sanitizer_depends}
blt::hip)
endif ()

blt_add_executable(
NAME sanitizer_tests
SOURCES sanitizer_tests.cpp
DEPENDS_ON umpire)
DEPENDS_ON ${sanitizer_depends})

include(FindPythonInterp)

Expand Down
11 changes: 6 additions & 5 deletions tests/tools/sanitizers/sanitizer_test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ def check_output(file_object, expected):
print("{BLUE}[ OK]{END} Found \"{expected}\"".format(expected=expected, **formatters))


def run_sanitizer_test(strategy, kind):
def run_sanitizer_test(strategy, kind, resource):
import subprocess
import os

cmd_args = ['./sanitizer_tests']
cmd_args.append(strategy)
cmd_args.append(kind)
cmd_args.append(resource)

test_program = subprocess.Popen(cmd_args,
stdout=subprocess.PIPE,
Expand All @@ -57,9 +58,9 @@ def run_sanitizer_test(strategy, kind):
import sys

print("{BLUE}[--------]{END}".format(**formatters))
run_sanitizer_test('DynamicPoolList', 'read')
run_sanitizer_test('DynamicPoolList', 'write')
run_sanitizer_test('QuickPool', 'read')
run_sanitizer_test('QuickPool', 'write')
run_sanitizer_test('DynamicPoolList', 'read', 'HOST')
run_sanitizer_test('DynamicPoolList', 'write', 'HOST')
run_sanitizer_test('QuickPool', 'read', 'HOST')
run_sanitizer_test('QuickPool', 'write', 'HOST')
print("{BLUE}[--------]{END}".format(**formatters))
sys.exit(errors)
99 changes: 69 additions & 30 deletions tests/tools/sanitizers/sanitizer_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,27 @@
#include "umpire/ResourceManager.hpp"
#include "umpire/strategy/DynamicPoolList.hpp"
#include "umpire/strategy/QuickPool.hpp"
#include "umpire/util/Macros.hpp"
#include "umpire/util/error.hpp"

void test_read_after_free()
#if defined(UMPIRE_ENABLE_HIP)
__global__ void test_read_for_hip(double* data_ptr, std::size_t INDEX)
{
auto& rm = umpire::ResourceManager::getInstance();
auto allocator = rm.getAllocator("test_allocator");

const std::size_t SIZE = 1356;
const std::size_t INDEX = SIZE / 2;
double* data = static_cast<double*>(allocator.allocate(SIZE * sizeof(double)));

data[INDEX] = 100;
std::cout << "data[INDEX] = " << data[INDEX] << std::endl;

allocator.deallocate(data);
std::cout << "data[256] = " << data[256] << std::endl;
if (threadIdx.x == 0) {
double dummy = data_ptr[INDEX];
dummy = dummy + 42;
}
}
__global__ void test_write_for_hip(double* data_ptr, std::size_t INDEX)
{
if (threadIdx.x == 0) {
data_ptr[INDEX] = 256;
data_ptr[INDEX] = INDEX + 42;
}
}
#endif

void test_write_after_free()
void sanitizer_test(const std::string test_type)
{
auto& rm = umpire::ResourceManager::getInstance();
auto allocator = rm.getAllocator("test_allocator");
Expand All @@ -37,36 +40,72 @@ void test_write_after_free()

data[INDEX] = 100;
std::cout << "data[INDEX] = " << data[INDEX] << std::endl;

allocator.deallocate(data);
data[INDEX] = -1;
std::cout << "data[INDEX] = " << data[INDEX] << std::endl;

if (test_type.find("read") != std::string::npos) {
#if defined(UMPIRE_ENABLE_HIP)
hipLaunchKernelGGL(test_read_for_hip, dim3(1), dim3(16), 0, 0, data, INDEX);
hipDeviceSynchronize();
#endif
std::cout << "data[256] = " << data[256] << std::endl;
} else {
if (test_type.find("write") == std::string::npos) {
std::cout << "Test type did not match either option - using write" << std::endl;
}
#if defined(UMPIRE_ENABLE_HIP)
hipLaunchKernelGGL(test_write_for_hip, dim3(1), dim3(16), 0, 0, data, INDEX);
hipDeviceSynchronize();
#endif
data[INDEX] = -1;
std::cout << "data[INDEX] = " << data[INDEX] << std::endl;
}
}

int main(int argc, char* argv[])
{
if (argc < 3) {
std::cout << argv[0] << " requires 2 arguments, test type and allocation strategy" << std::endl;
if (argc < 4) {
std::cout << "Usage: requires 3 arguments." << std::endl;
std::cout << "First, an allocation strategy (QuickPool or DynamicPoolList)." << std::endl;
std::cout << "Second, a test type (read or write)." << std::endl;
std::cout << "Third, a resource type (DEVICE, HOST, or UM)." << std::endl;
return 0;
}

const std::string strategy{argv[1]};
const std::string test_type{argv[2]};
std::string strategy{argv[1]};
std::string test_type{argv[2]};
std::string resource_type{argv[3]};

auto& rm = umpire::ResourceManager::getInstance();

if (strategy.find("QuickPool") != std::string::npos) {
auto pool = rm.makeAllocator<umpire::strategy::QuickPool>("test_allocator", rm.getAllocator("HOST"));
if ((resource_type.find("DEVICE") != std::string::npos) || (resource_type.find("UM") != std::string::npos)) {
#if !defined(UMPIRE_ENABLE_HIP)
UMPIRE_ERROR(umpire::runtime_error,
fmt::format("The resource, \"{}\", can't be used if HIP is not enabled.", resource_type));
#endif
} else {
if (resource_type.find("HOST") == std::string::npos) {
std::cout << "Resource type did not match any available options - using HOST." << std::endl;
resource_type = "HOST";
}
}

if (strategy.find("DynamicPoolList") != std::string::npos) {
auto pool = rm.makeAllocator<umpire::strategy::DynamicPoolList>("test_allocator", rm.getAllocator(resource_type));
UMPIRE_USE_VAR(pool);
} else if (strategy.find("DynamicPoolList") != std::string::npos) {
auto pool = rm.makeAllocator<umpire::strategy::DynamicPoolList>("test_allocator", rm.getAllocator("HOST"));
} else {
if (strategy.find("QuickPool") == std::string::npos) {
std::cout << "Allocation strategy did not match either option - using QuickPool." << std::endl;
strategy = "QuickPool";
}
auto pool = rm.makeAllocator<umpire::strategy::QuickPool>("test_allocator", rm.getAllocator(resource_type));
UMPIRE_USE_VAR(pool);
}

if (test_type.find("read") != std::string::npos) {
test_read_after_free();
} else if (test_type.find("write") != std::string::npos) {
test_write_after_free();
}
std::cout << " Conducting sanitizer test with " << strategy << " strategy, " << test_type << " test type, and the "
<< resource_type << " resource." << std::endl;

// Conduct the test
sanitizer_test(test_type);

return 0;
}
Loading