1#ifndef AMREX_TRACKED_VECTOR_H
2#define AMREX_TRACKED_VECTOR_H
4#include <AMReX_Config.H>
47 static_assert(std::is_trivially_copyable<T>(),
"TrackedVector can only hold trivially copyable types");
66 : m_data(std::make_shared<Data>(std::vector<T>(a_size))) {}
69 : m_data(std::make_shared<Data>(std::vector<T>(a_size, a_value))) {}
72 : m_data(std::make_shared<Data>(std::vector<T>(a_initializer_list))) {}
75 : m_data(std::make_shared<Data>(std::move(a_vector))) {}
85 std::swap(m_data, a_vector.m_data);
90 if (
this != &a_vector) {
98 if (
this != &a_vector) {
99 std::swap(m_data, a_vector.m_data);
113 [[nodiscard]] std::vector<T> &
128 [[nodiscard]] std::vector<T>
const &
146 require_amrex(
"device");
152 return m_data->device;
161 require_amrex(
"device_const");
166 return m_data->device;
171 device () {
return m_data->host; }
188 Data::drain_device(*m_data);
199 bool finalize_registered =
false;
204 explicit Data (std::vector<T> h)
223 static void drain_device (Data& d) {
226 d.host.resize(d.device.size());
227 if (!d.device.empty()) {
229 d.device.begin(), d.device.end(), d.host.begin());
233 d.device.shrink_to_fit();
240 static void require_amrex (
char const * func) {
242 throw std::runtime_error(
243 std::string(
"TrackedVector::") + func +
244 " called outside of AMReX initialize/finalize");
253 static void require_copyable_without_amrex (Data
const& src, Data
const& dst)
259 throw std::runtime_error(
260 "TrackedVector::copy_from: source is device_dirty "
261 "outside an AMReX session (host data is stale)");
263 if (!src.device.empty()) {
264 throw std::runtime_error(
265 "TrackedVector::copy_from: source retains device storage "
266 "outside an AMReX session");
268 if (!dst.device.empty()) {
269 throw std::runtime_error(
270 "TrackedVector::copy_from: destination retains device storage "
271 "outside an AMReX session");
273 if (src.finalize_registered) {
274 throw std::runtime_error(
275 "TrackedVector::copy_from: source finalize callback still registered "
276 "outside an AMReX session");
278 if (dst.finalize_registered) {
279 throw std::runtime_error(
280 "TrackedVector::copy_from: destination finalize callback still registered "
281 "outside an AMReX session");
289 Data
const& src = *a_vector.m_data;
290 require_copyable_without_amrex(src, *m_data);
293 m_data->status = src.status;
294 m_data->host = src.host;
304 m_data->device.clear();
305 m_data->device.shrink_to_fit();
312 m_data->device = src.device;
315 if (!m_data->finalize_registered) {
320 *m_data = *a_vector.m_data;
325 void to_device ()
const {
327 require_amrex(
"to_device");
328 auto const size = m_data->host.size();
330 m_data->device.resize(size);
332 m_data->host.begin(), m_data->host.end(), m_data->device.begin());
334 m_data->device.clear();
335 m_data->device.shrink_to_fit();
342 void to_host ()
const {
344 require_amrex(
"to_host");
346 m_data->host.resize(m_data->device.size());
347 if (!m_data->device.empty()) {
349 m_data->device.begin(), m_data->device.end(), m_data->host.begin());
360 void register_finalize ()
const {
362 require_amrex(
"register_finalize");
363 if (m_data->finalize_registered) {
return; }
364 m_data->finalize_registered =
true;
366 std::weak_ptr<Data> weak_data = m_data;
369 auto data = weak_data.lock();
370 if (!data) {
return; }
371 Data::drain_device(*data);
372 data->finalize_registered =
false;
380 mutable std::shared_ptr<Data> m_data = std::make_shared<Data>();
Dynamically allocated vector for trivially copyable data.
Definition AMReX_PODVector.H:308
Definition AMReX_BaseFwd.H:55
void copy(HostToDevice, InIter begin, InIter end, OutIter result) noexcept
A host-to-device copy routine. Note this is just a wrapper around memcpy, so it assumes contiguous st...
Definition AMReX_GpuContainers.H:128
static constexpr DeviceToHost deviceToHost
Definition AMReX_GpuContainers.H:106
static constexpr HostToDevice hostToDevice
Definition AMReX_GpuContainers.H:105
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:310
void ExecOnFinalize(std::function< void()>)
We maintain a stack of functions that need to be called in Finalize(). The functions are called in LI...
Definition AMReX.cpp:330
bool Initialized()
Returns true if there are any currently-active and initialized AMReX instances (i....
Definition AMReX.cpp:804
Definition AMReX_TrackedVector.H:46
Status status() const
Definition AMReX_TrackedVector.H:106
TrackedVector(TrackedVector const &a_vector)
Definition AMReX_TrackedVector.H:77
TrackedVector(size_type a_size, value_type const &a_value)
Definition AMReX_TrackedVector.H:68
T value_type
Definition AMReX_TrackedVector.H:48
device_vector_type & device()
Definition AMReX_TrackedVector.H:145
TrackedVector(std::vector< T > a_vector)
Definition AMReX_TrackedVector.H:74
TrackedVector(TrackedVector &&a_vector) noexcept
Definition AMReX_TrackedVector.H:83
std::vector< T > & host()
Definition AMReX_TrackedVector.H:114
TrackedVector & operator=(TrackedVector const &a_vector)
Definition AMReX_TrackedVector.H:89
device_vector_type const & device_const() const
Definition AMReX_TrackedVector.H:160
std::vector< T > const & host_const() const
Definition AMReX_TrackedVector.H:129
TrackedVector(size_type a_size)
Definition AMReX_TrackedVector.H:65
void release_gpu()
Definition AMReX_TrackedVector.H:185
std::size_t size_type
Definition AMReX_TrackedVector.H:49
amrex::Gpu::NonManagedDeviceVector< T > device_vector_type
Definition AMReX_TrackedVector.H:52
Status
Definition AMReX_TrackedVector.H:57
@ host_dirty
device data needs an update
@ up_to_date
host and device data are in sync
@ device_dirty
host data needs an update
TrackedVector(std::initializer_list< T > a_initializer_list)
Definition AMReX_TrackedVector.H:71