CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
442 lines
21 KiB
C++
442 lines
21 KiB
C++
/*
|
|
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include <hip_test_common.hh>
|
|
|
|
constexpr int kMemOrder = __ATOMIC_RELAXED;
|
|
constexpr int kMemScope = __HIP_MEMORY_SCOPE_SYSTEM;
|
|
|
|
// Trivially-copyable class.
|
|
class DummyTC {
|
|
public:
|
|
__device__ DummyTC() {}
|
|
__device__ ~DummyTC() = default;
|
|
__device__ DummyTC(const DummyTC&) = default;
|
|
__device__ DummyTC& operator=(const DummyTC&) = default;
|
|
__device__ DummyTC(DummyTC&&) = default;
|
|
__device__ DummyTC& operator=(DummyTC&&) = default;
|
|
};
|
|
|
|
class Dummy {
|
|
public:
|
|
__device__ Dummy() {}
|
|
__device__ ~Dummy() {}
|
|
};
|
|
|
|
__global__ void StoreCompileKernel(int* x) {
|
|
// Valid combinations
|
|
__hip_atomic_store(x, 1, __ATOMIC_RELAXED, kMemScope);
|
|
__hip_atomic_store(x, 1, __ATOMIC_RELEASE, kMemScope);
|
|
__hip_atomic_store(x, 1, __ATOMIC_SEQ_CST, kMemScope);
|
|
|
|
// Pointer to a non-const type
|
|
__hip_atomic_store(reinterpret_cast<const int*>(x), 1, kMemOrder, kMemScope);
|
|
// Value instead of pointer to the atomic builtin
|
|
__hip_atomic_store(*x, 1, kMemOrder, kMemScope);
|
|
// Consume not allowed by C++1 for store
|
|
__hip_atomic_store(x, 1, __ATOMIC_CONSUME, kMemScope);
|
|
// Acquire not allowed by C++11 for store
|
|
__hip_atomic_store(x, 1, __ATOMIC_ACQUIRE, kMemScope);
|
|
// Acquire-Release not allowed by C++11 for store
|
|
__hip_atomic_store(x, 1, __ATOMIC_ACQ_REL, kMemScope);
|
|
// Memory order is out of bounds
|
|
__hip_atomic_store(x, 1, -1, kMemScope);
|
|
__hip_atomic_store(x, 1, 10, kMemScope);
|
|
// Memory scope is out of bounds
|
|
__hip_atomic_store(x, 1, kMemOrder, -1);
|
|
__hip_atomic_store(x, 1, kMemOrder, 10);
|
|
|
|
// Storing an object that is not trivially-copyable
|
|
Dummy dummy_a{};
|
|
Dummy dummy_b{};
|
|
__hip_atomic_store(&dummy_a, dummy_b, kMemOrder, kMemScope);
|
|
|
|
// Storing an object that is trivially-copyable
|
|
DummyTC dummytc_a{};
|
|
DummyTC dummytc_b{};
|
|
__hip_atomic_store(&dummytc_a, dummytc_b, kMemOrder, kMemScope);
|
|
}
|
|
|
|
__global__ void LoadCompileKernel(int* x, int* y) {
|
|
// Valid combinations
|
|
*y = __hip_atomic_load(x, __ATOMIC_RELAXED, kMemScope);
|
|
*y = __hip_atomic_load(x, __ATOMIC_CONSUME, kMemScope);
|
|
*y = __hip_atomic_load(x, __ATOMIC_ACQUIRE, kMemScope);
|
|
*y = __hip_atomic_load(x, __ATOMIC_SEQ_CST, kMemScope);
|
|
|
|
// Value instead of pointer to the atomic builtin for 1st parameter
|
|
*y = __hip_atomic_load(*x, kMemOrder, kMemScope);
|
|
// Release not allowed by C++11 for load
|
|
*y = __hip_atomic_load(x, __ATOMIC_RELEASE, kMemScope);
|
|
// Acquire-Release not allowed by C++11 for load
|
|
*y = __hip_atomic_load(x, __ATOMIC_ACQ_REL, kMemScope);
|
|
// Memory order is out of bounds
|
|
*y = __hip_atomic_load(x, -1, kMemScope);
|
|
*y = __hip_atomic_load(x, 10, kMemScope);
|
|
// Memory scope is out of bounds
|
|
*y = __hip_atomic_load(x, kMemOrder, -1);
|
|
*y = __hip_atomic_load(x, kMemOrder, 10);
|
|
|
|
// Loading an object that is not trivially-copyable
|
|
Dummy dummy_a{};
|
|
Dummy dummy_b{};
|
|
dummy_a = __hip_atomic_load(&dummy_b, kMemOrder, kMemScope);
|
|
|
|
// Loading an object that is trivially-copyable
|
|
DummyTC dummytc_a{};
|
|
DummyTC dummytc_b{};
|
|
dummytc_a = __hip_atomic_load(&dummytc_b, kMemOrder, kMemScope);
|
|
}
|
|
|
|
__global__ void CompareWeakCompileKernel(int* x, int* expected) {
|
|
bool res{false};
|
|
// Valid combinations
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_CONSUME, __ATOMIC_RELAXED,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_CONSUME, __ATOMIC_CONSUME,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_ACQUIRE, __ATOMIC_CONSUME,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_RELEASE, __ATOMIC_RELAXED,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_RELEASE, __ATOMIC_CONSUME,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_ACQ_REL, __ATOMIC_CONSUME,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_SEQ_CST, __ATOMIC_CONSUME,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_SEQ_CST, __ATOMIC_ACQ_REL,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST,
|
|
kMemScope);
|
|
|
|
// Release not allowed on fail by C++11
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, kMemOrder, __ATOMIC_RELEASE, kMemScope);
|
|
// Acquire-Release not allowed on fail by C++11
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, kMemOrder, __ATOMIC_ACQ_REL, kMemScope);
|
|
// Fail stronger than success
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, __ATOMIC_RELAXED, __ATOMIC_SEQ_CST,
|
|
kMemScope);
|
|
// Pointer to a non-const type
|
|
res = __hip_atomic_compare_exchange_weak(reinterpret_cast<const int*>(x), expected, 1, kMemOrder,
|
|
kMemOrder, kMemScope);
|
|
// Value instead of pointer to the atomic builtin
|
|
res = __hip_atomic_compare_exchange_weak(*x, expected, 1, kMemOrder, kMemOrder, kMemScope);
|
|
// Memory order on success is out of bounds
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, -1, kMemOrder, kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, 10, kMemOrder, kMemScope);
|
|
// Memory order on failure is out of bounds
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, kMemOrder, -1, kMemScope);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, kMemOrder, 10, kMemScope);
|
|
// Memory scope is out of bounds
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, kMemOrder, kMemOrder, -1);
|
|
res = __hip_atomic_compare_exchange_weak(x, expected, 1, kMemOrder, kMemOrder, 10);
|
|
|
|
// User-defined class is not trivially-copyable and therefore cannot be atomically copied
|
|
Dummy dummy_a{};
|
|
Dummy dummy_b{};
|
|
Dummy dummy_c{};
|
|
res = __hip_atomic_compare_exchange_weak(&dummy_a, &dummy_b, dummy_c, kMemOrder, kMemOrder,
|
|
kMemScope);
|
|
// User-defined class is trivially-copyable and can be atomically copied
|
|
DummyTC dummytc_a{};
|
|
DummyTC dummytc_b{};
|
|
DummyTC dummytc_c{};
|
|
res = __hip_atomic_compare_exchange_weak(&dummytc_a, &dummytc_b, dummytc_c, kMemOrder, kMemOrder,
|
|
kMemScope);
|
|
}
|
|
|
|
__global__ void CompareStrongCompileKernel(int* x, int* expected) {
|
|
bool res{false};
|
|
// Valid combinations
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_CONSUME, __ATOMIC_RELAXED,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_CONSUME, __ATOMIC_CONSUME,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_ACQUIRE, __ATOMIC_CONSUME,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_RELEASE, __ATOMIC_RELAXED,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_RELEASE, __ATOMIC_CONSUME,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_ACQ_REL, __ATOMIC_CONSUME,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_SEQ_CST, __ATOMIC_CONSUME,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_SEQ_CST, __ATOMIC_ACQ_REL,
|
|
kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST,
|
|
kMemScope);
|
|
|
|
// Release not allowed on fail by C++11
|
|
res =
|
|
__hip_atomic_compare_exchange_strong(x, expected, 1, kMemOrder, __ATOMIC_RELEASE, kMemScope);
|
|
// Acquire-Release not allowed on fail by C++11
|
|
res =
|
|
__hip_atomic_compare_exchange_strong(x, expected, 1, kMemOrder, __ATOMIC_ACQ_REL, kMemScope);
|
|
// Fail stronger than success
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, __ATOMIC_RELAXED, __ATOMIC_SEQ_CST,
|
|
kMemScope);
|
|
// Pointer to a non-const type
|
|
res = __hip_atomic_compare_exchange_strong(reinterpret_cast<const int*>(x), expected, 1,
|
|
kMemOrder, kMemOrder, kMemScope);
|
|
// Value instead of pointer to the atomic builtin for 1st parameter
|
|
res = __hip_atomic_compare_exchange_strong(*x, expected, 1, kMemOrder, kMemOrder, kMemScope);
|
|
// Memory order on success is out of bounds
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, -1, kMemOrder, kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, 10, kMemOrder, kMemScope);
|
|
// Memory order on failure is out of bounds
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, kMemOrder, -1, kMemScope);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, kMemOrder, 10, kMemScope);
|
|
// Memory scope is out of bounds
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, kMemOrder, kMemOrder, -1);
|
|
res = __hip_atomic_compare_exchange_strong(x, expected, 1, kMemOrder, kMemOrder, 10);
|
|
|
|
// User-defined class is not trivially-copyable and therefore cannot be atomically copied
|
|
Dummy dummy_a{};
|
|
Dummy dummy_b{};
|
|
Dummy dummy_c{};
|
|
res = __hip_atomic_compare_exchange_strong(&dummy_a, &dummy_b, dummy_c, kMemOrder, kMemOrder,
|
|
kMemScope);
|
|
// User-defined class is trivially-copyable and can be atomically copied
|
|
DummyTC dummytc_a{};
|
|
DummyTC dummytc_b{};
|
|
DummyTC dummytc_c{};
|
|
res = __hip_atomic_compare_exchange_strong(&dummytc_a, &dummytc_b, dummytc_c, kMemOrder,
|
|
kMemOrder, kMemScope);
|
|
}
|
|
|
|
__global__ void ExchangeCompileKernel(int* x) {
|
|
int old{};
|
|
// Valid combinations
|
|
old = __hip_atomic_exchange(x, 1, __ATOMIC_RELAXED, kMemScope);
|
|
old = __hip_atomic_exchange(x, 1, __ATOMIC_CONSUME, kMemScope);
|
|
old = __hip_atomic_exchange(x, 1, __ATOMIC_ACQUIRE, kMemScope);
|
|
old = __hip_atomic_exchange(x, 1, __ATOMIC_RELEASE, kMemScope);
|
|
old = __hip_atomic_exchange(x, 1, __ATOMIC_ACQ_REL, kMemScope);
|
|
old = __hip_atomic_exchange(x, 1, __ATOMIC_SEQ_CST, kMemScope);
|
|
|
|
// Pointer to a non-const type
|
|
old = __hip_atomic_exchange(reinterpret_cast<const int*>(x), 1, kMemOrder, kMemScope);
|
|
// Value instead of pointer to the atomic builtin
|
|
old = __hip_atomic_exchange(*x, 1, kMemOrder, kMemScope);
|
|
// Memory order out of bounds
|
|
old = __hip_atomic_exchange(x, 1, -1, kMemScope);
|
|
old = __hip_atomic_exchange(x, 1, 10, kMemScope);
|
|
// Memory scope out of bounds
|
|
old = __hip_atomic_exchange(x, 1, kMemOrder, -1);
|
|
old = __hip_atomic_exchange(x, 1, kMemOrder, 10);
|
|
|
|
// User-defined class is not trivially-copyable and therefore cannot be atomically copied
|
|
Dummy dummy_a{};
|
|
Dummy dummy_b{};
|
|
dummy_b = __hip_atomic_exchange(&dummy_a, dummy_b, kMemOrder, kMemScope);
|
|
|
|
// User-defined class is trivially-copyable and can be atomically copied
|
|
DummyTC dummytc_a{};
|
|
DummyTC dummytc_b{};
|
|
dummytc_b = __hip_atomic_exchange(&dummytc_a, dummytc_b, kMemOrder, kMemScope);
|
|
}
|
|
|
|
__global__ void FetchAddCompileKernel(int* x) {
|
|
int old{};
|
|
// Valid combinations
|
|
old = __hip_atomic_fetch_add(x, 1, __ATOMIC_RELAXED, kMemScope);
|
|
old = __hip_atomic_fetch_add(x, 1, __ATOMIC_CONSUME, kMemScope);
|
|
old = __hip_atomic_fetch_add(x, 1, __ATOMIC_ACQUIRE, kMemScope);
|
|
old = __hip_atomic_fetch_add(x, 1, __ATOMIC_RELEASE, kMemScope);
|
|
old = __hip_atomic_fetch_add(x, 1, __ATOMIC_ACQ_REL, kMemScope);
|
|
old = __hip_atomic_fetch_add(x, 1, __ATOMIC_SEQ_CST, kMemScope);
|
|
|
|
// Pointer to a non-const type
|
|
old = __hip_atomic_fetch_add(reinterpret_cast<const int*>(x), 1, kMemOrder, kMemScope);
|
|
// Value instead of pointer to the atomic builtin
|
|
old = __hip_atomic_fetch_add(*x, 1, kMemOrder, kMemScope);
|
|
// Memory order out of bounds
|
|
old = __hip_atomic_fetch_add(x, 1, -1, kMemScope);
|
|
old = __hip_atomic_fetch_add(x, 1, 10, kMemScope);
|
|
// Memory scope out of bounds
|
|
old = __hip_atomic_fetch_add(x, 1, kMemOrder, -1);
|
|
old = __hip_atomic_fetch_add(x, 1, kMemOrder, 10);
|
|
|
|
Dummy dummy{};
|
|
old = __hip_atomic_fetch_add(&dummy, 1, kMemOrder, kMemScope);
|
|
}
|
|
|
|
__global__ void FetchAndCompileKernel(int* x) {
|
|
int old{};
|
|
// Valid combinations
|
|
old = __hip_atomic_fetch_and(x, 1, __ATOMIC_RELAXED, kMemScope);
|
|
old = __hip_atomic_fetch_and(x, 1, __ATOMIC_CONSUME, kMemScope);
|
|
old = __hip_atomic_fetch_and(x, 1, __ATOMIC_ACQUIRE, kMemScope);
|
|
old = __hip_atomic_fetch_and(x, 1, __ATOMIC_RELEASE, kMemScope);
|
|
old = __hip_atomic_fetch_and(x, 1, __ATOMIC_ACQ_REL, kMemScope);
|
|
old = __hip_atomic_fetch_and(x, 1, __ATOMIC_SEQ_CST, kMemScope);
|
|
|
|
// Pointer to a non-const type
|
|
old = __hip_atomic_fetch_and(reinterpret_cast<const int*>(x), 1, kMemOrder, kMemScope);
|
|
// Value instead of pointer to the atomic builtin
|
|
old = __hip_atomic_fetch_and(*x, 1, kMemOrder, kMemScope);
|
|
// Memory order out of bounds
|
|
old = __hip_atomic_fetch_and(x, 1, -1, kMemScope);
|
|
old = __hip_atomic_fetch_and(x, 1, 10, kMemScope);
|
|
// Memory scope out of bounds
|
|
old = __hip_atomic_fetch_and(x, 1, kMemOrder, -1);
|
|
old = __hip_atomic_fetch_and(x, 1, kMemOrder, 10);
|
|
|
|
// Value must be an integer
|
|
Dummy dummy{};
|
|
old = __hip_atomic_fetch_and(&dummy, 1, kMemOrder, kMemScope);
|
|
float float_var{1.5f};
|
|
old = __hip_atomic_fetch_and(&float_var, 1, kMemOrder, kMemScope);
|
|
double double_var{1.5};
|
|
old = __hip_atomic_fetch_and(&double_var, 1, kMemOrder, kMemScope);
|
|
}
|
|
|
|
__global__ void FetchOrCompileKernel(int* x) {
|
|
int old{};
|
|
// Valid combinations
|
|
old = __hip_atomic_fetch_or(x, 1, __ATOMIC_RELAXED, kMemScope);
|
|
old = __hip_atomic_fetch_or(x, 1, __ATOMIC_CONSUME, kMemScope);
|
|
old = __hip_atomic_fetch_or(x, 1, __ATOMIC_ACQUIRE, kMemScope);
|
|
old = __hip_atomic_fetch_or(x, 1, __ATOMIC_RELEASE, kMemScope);
|
|
old = __hip_atomic_fetch_or(x, 1, __ATOMIC_ACQ_REL, kMemScope);
|
|
old = __hip_atomic_fetch_or(x, 1, __ATOMIC_SEQ_CST, kMemScope);
|
|
|
|
// Pointer to a non-const type
|
|
old = __hip_atomic_fetch_or(reinterpret_cast<const int*>(x), 1, kMemOrder, kMemScope);
|
|
// Value instead of pointer to the atomic builtin
|
|
old = __hip_atomic_fetch_or(*x, 1, kMemOrder, kMemScope);
|
|
// Memory order out of bounds
|
|
old = __hip_atomic_fetch_or(x, 1, -1, kMemScope);
|
|
old = __hip_atomic_fetch_or(x, 1, 10, kMemScope);
|
|
// Memory scope out of bounds
|
|
old = __hip_atomic_fetch_or(x, 1, kMemOrder, -1);
|
|
old = __hip_atomic_fetch_or(x, 1, kMemOrder, 10);
|
|
|
|
// Value must be an integer
|
|
Dummy dummy{};
|
|
old = __hip_atomic_fetch_or(&dummy, 1, kMemOrder, kMemScope);
|
|
float float_var{1.5f};
|
|
old = __hip_atomic_fetch_or(&float_var, 1, kMemOrder, kMemScope);
|
|
double double_var{1.5};
|
|
old = __hip_atomic_fetch_or(&double_var, 1, kMemOrder, kMemScope);
|
|
}
|
|
|
|
__global__ void FetchXorCompileKernel(int* x) {
|
|
int old{};
|
|
// Valid combinations
|
|
old = __hip_atomic_fetch_xor(x, 1, __ATOMIC_RELAXED, kMemScope);
|
|
old = __hip_atomic_fetch_xor(x, 1, __ATOMIC_CONSUME, kMemScope);
|
|
old = __hip_atomic_fetch_xor(x, 1, __ATOMIC_ACQUIRE, kMemScope);
|
|
old = __hip_atomic_fetch_xor(x, 1, __ATOMIC_RELEASE, kMemScope);
|
|
old = __hip_atomic_fetch_xor(x, 1, __ATOMIC_ACQ_REL, kMemScope);
|
|
old = __hip_atomic_fetch_xor(x, 1, __ATOMIC_SEQ_CST, kMemScope);
|
|
|
|
// Pointer to a non-const type
|
|
old = __hip_atomic_fetch_xor(reinterpret_cast<const int*>(x), 1, kMemOrder, kMemScope);
|
|
// Value instead of pointer to the atomic builtin
|
|
old = __hip_atomic_fetch_xor(*x, 1, kMemOrder, kMemScope);
|
|
// Memory order out of bounds
|
|
old = __hip_atomic_fetch_xor(x, 1, -1, kMemScope);
|
|
old = __hip_atomic_fetch_xor(x, 1, 10, kMemScope);
|
|
// Memory scope out of bounds
|
|
old = __hip_atomic_fetch_xor(x, 1, kMemOrder, -1);
|
|
old = __hip_atomic_fetch_xor(x, 1, kMemOrder, 10);
|
|
|
|
// Value must be an integer
|
|
Dummy dummy{};
|
|
old = __hip_atomic_fetch_xor(&dummy, 1, kMemOrder, kMemScope);
|
|
float float_var{1.5f};
|
|
old = __hip_atomic_fetch_xor(&float_var, 1, kMemOrder, kMemScope);
|
|
double double_var{1.5};
|
|
old = __hip_atomic_fetch_xor(&double_var, 1, kMemOrder, kMemScope);
|
|
}
|
|
|
|
__global__ void FetchMaxCompileKernel(int* x) {
|
|
int old{};
|
|
// Valid combinations
|
|
old = __hip_atomic_fetch_max(x, 1, __ATOMIC_RELAXED, kMemScope);
|
|
old = __hip_atomic_fetch_max(x, 1, __ATOMIC_CONSUME, kMemScope);
|
|
old = __hip_atomic_fetch_max(x, 1, __ATOMIC_ACQUIRE, kMemScope);
|
|
old = __hip_atomic_fetch_max(x, 1, __ATOMIC_RELEASE, kMemScope);
|
|
old = __hip_atomic_fetch_max(x, 1, __ATOMIC_ACQ_REL, kMemScope);
|
|
old = __hip_atomic_fetch_max(x, 1, __ATOMIC_SEQ_CST, kMemScope);
|
|
|
|
// Pointer to a non-const type
|
|
old = __hip_atomic_fetch_max(reinterpret_cast<const int*>(x), 1, kMemOrder, kMemScope);
|
|
// Value instead of pointer to the atomic builtin
|
|
old = __hip_atomic_fetch_max(*x, 1, kMemOrder, kMemScope);
|
|
// Memory order out of bounds
|
|
old = __hip_atomic_fetch_max(x, 1, -1, kMemScope);
|
|
old = __hip_atomic_fetch_max(x, 1, 10, kMemScope);
|
|
// Memory scope out of bounds
|
|
old = __hip_atomic_fetch_max(x, 1, kMemOrder, -1);
|
|
old = __hip_atomic_fetch_max(x, 1, kMemOrder, 10);
|
|
|
|
// Value must be integer or floating point type
|
|
Dummy dummy{};
|
|
old = __hip_atomic_fetch_max(&dummy, 1, kMemOrder, kMemScope);
|
|
}
|
|
|
|
__global__ void FetchMinCompileKernel(int* x) {
|
|
int old{};
|
|
// Valid combinations
|
|
old = __hip_atomic_fetch_min(x, 1, __ATOMIC_RELAXED, kMemScope);
|
|
old = __hip_atomic_fetch_min(x, 1, __ATOMIC_CONSUME, kMemScope);
|
|
old = __hip_atomic_fetch_min(x, 1, __ATOMIC_ACQUIRE, kMemScope);
|
|
old = __hip_atomic_fetch_min(x, 1, __ATOMIC_RELEASE, kMemScope);
|
|
old = __hip_atomic_fetch_min(x, 1, __ATOMIC_ACQ_REL, kMemScope);
|
|
old = __hip_atomic_fetch_min(x, 1, __ATOMIC_SEQ_CST, kMemScope);
|
|
|
|
// Pointer to a non-const type
|
|
old = __hip_atomic_fetch_min(reinterpret_cast<const int*>(x), 1, kMemOrder, kMemScope);
|
|
// Value instead of pointer to the atomic builtin
|
|
old = __hip_atomic_fetch_min(*x, 1, kMemOrder, kMemScope);
|
|
// Memory order out of bounds
|
|
old = __hip_atomic_fetch_min(x, 1, -1, kMemScope);
|
|
old = __hip_atomic_fetch_min(x, 1, 10, kMemScope);
|
|
// Memory scope out of bounds
|
|
old = __hip_atomic_fetch_min(x, 1, kMemOrder, -1);
|
|
old = __hip_atomic_fetch_min(x, 1, kMemOrder, 10);
|
|
|
|
// Value must be integer or floating point type
|
|
Dummy dummy{};
|
|
old = __hip_atomic_fetch_min(&dummy, 1, kMemOrder, kMemScope);
|
|
}
|