vecmem 1.14.0
Loading...
Searching...
No Matches
cuda_device_atomic_ref.ipp
1/*
2 * VecMem project, part of the ACTS project (R&D line)
3 *
4 * (c) 2022-2024 CERN for the benefit of the ACTS project
5 *
6 * Mozilla Public License Version 2.0
7 */
8#pragma once
9
10// System include(s).
11#include <cassert>
12
13namespace vecmem {
14namespace cuda {
15
16template <typename T, device_address_space address>
19 : m_ptr(&ref) {}
20
21template <typename T, device_address_space address>
23 const device_atomic_ref& parent)
24 : m_ptr(parent.m_ptr) {}
25
26template <typename T, device_address_space address>
27VECMEM_HOST_AND_DEVICE auto device_atomic_ref<T, address>::operator=(
28 value_type data) const -> value_type {
29
30 store(data);
31 return data;
32}
33
34// Only invoke __threadfence() during device code compilation. Without this,
35// nvcc gets upset about calling this **device only** function from a function
36// labeled HOST_AND_DEVICE. Allow an outside source to set the macro, so that
37// vecmem::hip::device_atomic_ref could have its own logic for setting it up
38// correctly.
39#ifndef __VECMEM_THREADFENCE
40#ifdef __CUDA_ARCH__
41#define __VECMEM_THREADFENCE __threadfence()
42#else
43#define __VECMEM_THREADFENCE
44#endif // defined(__CUDA_ARCH__)
45#endif // not defined(__VECMEM_THREADFENCE)
46
47template <typename T, device_address_space address>
48VECMEM_HOST_AND_DEVICE void device_atomic_ref<T, address>::store(
49 value_type data, memory_order) const {
50
51 volatile pointer addr = m_ptr;
52 __VECMEM_THREADFENCE;
53 *addr = data;
54}
55
56template <typename T, device_address_space address>
57VECMEM_HOST_AND_DEVICE auto device_atomic_ref<T, address>::load(
58 memory_order) const -> value_type {
59
60 volatile pointer addr = m_ptr;
61 __VECMEM_THREADFENCE;
62 const value_type value = *addr;
63 __VECMEM_THREADFENCE;
64 return value;
65}
66
67#undef __VECMEM_THREADFENCE
68
69template <typename T, device_address_space address>
70VECMEM_HOST_AND_DEVICE auto device_atomic_ref<T, address>::exchange(
71 value_type data, memory_order) const -> value_type {
72
73 return atomicExch(m_ptr, data);
74}
75
76template <typename T, device_address_space address>
77VECMEM_HOST_AND_DEVICE bool
80
81 if (order == memory_order::acq_rel) {
82 return compare_exchange_strong(expected, desired, order,
83 memory_order::acquire);
84 } else if (order == memory_order::release) {
85 return compare_exchange_strong(expected, desired, order,
86 memory_order::relaxed);
87 } else {
88 return compare_exchange_strong(expected, desired, order, order);
89 }
90}
91
92template <typename T, device_address_space address>
93VECMEM_HOST_AND_DEVICE bool
96 memory_order failure) const {
97
99 assert(failure != memory_order::release &&
100 failure != memory_order::acq_rel);
101
102 const value_type r = atomicCAS(m_ptr, expected, desired);
103 // atomicCAS returns the old value, so the change will have succeeded if
104 // the old value was the expected value.
105 if (r == expected) {
106 return true;
107 } else {
108 expected = r;
109 return false;
110 }
111}
112
113template <typename T, device_address_space address>
115 value_type data, memory_order) const -> value_type {
116
117 return atomicAdd(m_ptr, data);
118}
119
120template <typename T, device_address_space address>
122 value_type data, memory_order) const -> value_type {
123
124 return atomicSub(m_ptr, data);
125}
126
127template <typename T, device_address_space address>
129 value_type data, memory_order) const -> value_type {
130
131 return atomicAnd(m_ptr, data);
132}
133
134template <typename T, device_address_space address>
135VECMEM_HOST_AND_DEVICE auto device_atomic_ref<T, address>::fetch_or(
136 value_type data, memory_order) const -> value_type {
137
138 return atomicOr(m_ptr, data);
139}
140
141template <typename T, device_address_space address>
143 value_type data, memory_order) const -> value_type {
144
145 return atomicXor(m_ptr, data);
146}
147
148} // namespace cuda
149} // namespace vecmem
Custom implementation for atomic operations in CUDA device code.
Definition cuda_device_atomic_ref.hpp:34
T value_type
Type managed by the object.
Definition cuda_device_atomic_ref.hpp:41
value_type & reference
Reference to a value given by the user.
Definition cuda_device_atomic_ref.hpp:47
value_type * pointer
Pointer to the value in global memory.
Definition cuda_device_atomic_ref.hpp:45
VECMEM_HOST_AND_DEVICE value_type fetch_sub(value_type data, memory_order order=memory_order::seq_cst) const
Substitute a chosen value from the stored variable.
Definition dummy_device_atomic_ref.ipp:107
VECMEM_HOST_AND_DEVICE value_type exchange(value_type data, memory_order order=memory_order::seq_cst) const
Exchange the current value of the variable with a different one.
Definition dummy_device_atomic_ref.ipp:55
VECMEM_HOST_AND_DEVICE void store(value_type data, memory_order order=memory_order::seq_cst) const
Set the variable to the desired value.
Definition dummy_device_atomic_ref.ipp:39
VECMEM_HOST_AND_DEVICE value_type fetch_add(value_type data, memory_order order=memory_order::seq_cst) const
Add a chosen value to the stored variable.
Definition dummy_device_atomic_ref.ipp:97
dummy_device_atomic_ref & operator=(const dummy_device_atomic_ref &)=delete
Disable the assignment operator.
VECMEM_HOST_AND_DEVICE value_type load(memory_order order=memory_order::seq_cst) const
Get the value of the variable.
Definition dummy_device_atomic_ref.ipp:46
VECMEM_HOST_AND_DEVICE value_type fetch_and(value_type data, memory_order order=memory_order::seq_cst) const
Replace the current value with the specified value AND-ed to it.
Definition dummy_device_atomic_ref.ipp:117
VECMEM_HOST_AND_DEVICE value_type fetch_or(value_type data, memory_order order=memory_order::seq_cst) const
Replace the current value with the specified value OR-d to it.
Definition dummy_device_atomic_ref.ipp:127
VECMEM_HOST_AND_DEVICE bool compare_exchange_strong(reference expected, value_type desired, memory_order success, memory_order failure) const
Compare against the current value, and exchange only if different.
Definition dummy_device_atomic_ref.ipp:82
VECMEM_HOST_AND_DEVICE value_type fetch_xor(value_type data, memory_order order=memory_order::seq_cst) const
Replace the current value with the specified value XOR-d to it.
Definition dummy_device_atomic_ref.ipp:137
Main namespace for the vecmem classes/functions.
Definition atomic_ref.hpp:16
std::vector< T, vecmem::polymorphic_allocator< T > > vector
Alias type for vectors with our polymorphic allocator.
Definition vector.hpp:35
memory_order
Custom (dummy) definition for the memory order.
Definition memory_order.hpp:31