apoCHARMM 1.0.0
High-performance molecular dynamics simulations on GPUs
 
Loading...
Searching...
No Matches
CudaContainer< T > Class Template Reference

Owns explicity synchronized host and CUDA-device array mirrors. More...

#include <CudaContainer.h>

Public Member Functions

 CudaContainer (void)
 Constructs an empty host/device container.
 
 CudaContainer (const std::size_t count)
 Constructs host and device mirrors with the requested length.
 
 CudaContainer (const std::vector< T > &other)
 Constructs coherent mirrors by copying a host vector.
 
 CudaContainer (const std::vector< T > &&other)
 Constructs coherent mirrors by copying a const host-vector rvalue.
 
 CudaContainer (const DeviceVector< T > &other)
 Constructs coherent mirrors by copying a device vector.
 
 CudaContainer (const DeviceVector< T > &&other)
 Constructs coherent mirrors by copying a const device-vector rvalue.
 
 CudaContainer (const CudaContainer< T > &other)
 Constructs independent copies of another container's two mirrors.
 
 CudaContainer (const CudaContainer< T > &&other)
 Constructs independent copies of a const container rvalue.
 
 ~CudaContainer (void) noexcept=default
 Destroys both owned mirrors without propagating cleanup failures.
 
CudaContainer< T > & operator= (const std::vector< T > &other)
 Replaces both mirrors with a coherent copy of a host vector.
 
CudaContainer< T > & operator= (const std::vector< T > &&other)
 Replaces both mirrors with a copy of a const host-vector rvalue.
 
CudaContainer< T > & operator= (const DeviceVector< T > &other)
 Replaces both mirrors with a coherent copy of a device vector.
 
CudaContainer< T > & operator= (const DeviceVector< T > &&other)
 Replaces both mirrors with a copy of a const device-vector rvalue.
 
CudaContainer< T > & operator= (const CudaContainer< T > &other)
 Replaces each mirror with the corresponding mirror from another container.
 
CudaContainer< T > & operator= (const CudaContainer< T > &&other)
 Replaces each mirror with copies from a const container rvalue.
 
const T & at (const std::size_t pos) const
 Returns a checked const reference to one host element.
 
T & at (const std::size_t pos)
 Returns a checked mutable reference to one host element.
 
const T & operator[] (const std::size_t pos) const
 Returns an unchecked const reference to one host element.
 
T & operator[] (const std::size_t pos)
 Returns an unchecked mutable reference to one host element.
 
const std::vector< T > & getHostArray (void) const
 Returns a borrowed const reference to the host mirror.
 
std::vector< T > & getHostArray (void)
 Returns a borrowed mutable reference to the host mirror.
 
const DeviceVector< T > & getDeviceArray (void) const
 Returns a borrowed const reference to the device mirror.
 
DeviceVector< T > & getDeviceArray (void)
 Returns a borrowed mutable reference to the device mirror.
 
std::size_t size (void) const
 Returns the active length of the host mirror.
 
void shrink_to_fit (void)
 Requests capacity reduction for both mirrors without transferring values.
 
void clear (void)
 Clears both mirrors and releases the device allocation.
 
void push_back (const T &value)
 Appends one value to both mirrors.
 
void resize (const std::size_t count)
 Resizes both active ranges without synchronizing their values.
 
void set (const std::vector< T > &values)
 Replaces both mirrors with a coherent host-vector copy.
 
void set (const DeviceVector< T > &values)
 Replaces both mirrors with a coherent device-vector copy.
 
void set (const T value)
 Sets every current element to one value in both mirrors.
 
void setToValue (const T value)
 Sets every current element to one value in both mirrors.
 
void transferToDevice (void)
 Transfers the complete host mirror to device memory.
 
void transferToHost (void)
 Transfers the complete device mirror to host memory.
 
void transferFromDevice (void)
 Transfers the complete device mirror to host memory.
 
void transferFromHost (void)
 Transfers the complete host mirror to device memory.
 
void printDeviceArray (void) const
 Prints the active device mirror with CUDA device printf.
 

Detailed Description

template<typename T>
class CudaContainer< T >

Owns explicity synchronized host and CUDA-device array mirrors.

CudaContainer<T> stores one contiguous std::vector<T> in host memory and one contiguous DeviceVector in CUDA device memory. Construction from one source establishes equal active lengths. Copying another container preserves any source divergence, and mutable mirror access can introduce new divergence. Element values are synchronized only by constructors, assignments, set(), and the explicit transfer methods documented below. Host element access never performs an implicit device transfer.

Both mirrors are owned exclusively by the container. Accessors return borrowed references; they do not transfer ownership. Mutable mirror access is an escape hatch that can make the active lengths or values diverge. Transfer and print operations rely on the caller preserving equal active lengths and valid storage after using that escape hatch.

CUDA operations use the CUDA runtime state current on the calling thread. The class does not retain a CUDA device identifier or stream and provides no internal host-thread synchronization.

Template Parameters
TElement representation copied byte-for-byte between host and device memory. The library currently instantiates int, int2, int3, int4, unsigned int, float, float2, float3, float4, long long int, longlong2, longlong3, longlong4, unsigned long long int, std::size_t, double, double2, double3, and double4.
Note
The container assigns no physical meaning or AKMA unit to T. Units and component interpretation belong to the owning subsystem.
Warning
Operations that update both mirrors are sequential rather than transactional. A failure after one mirror changes can leave the two mirrors divergent.
The class is not thread-safe. Callers must serialize overlapping access whenever any operation can mutate either mirror or its contents.
See also
cuda_container
DeviceVector

Constructor & Destructor Documentation

◆ CudaContainer() [1/8]

template<typename T >
CudaContainer< T >::CudaContainer ( void  )

Constructs an empty host/device container.

Neither mirror owns an allocation and both active lengths are zero.

Postcondition
size() == 0, getHostArray().empty() is true, and getDeviceArray().empty() is true.

◆ CudaContainer() [2/8]

template<typename T >
CudaContainer< T >::CudaContainer ( const std::size_t  count)

Constructs host and device mirrors with the requested length.

The host elements are value-initialized by std::vector<T>. The device allocation contains unspecified bytes; this constructor does not transfer the host values to the device or synchronize the CUDA device.

Parameters
[in]countDimensionless number of elements in each mirror. The byte count count * sizeof(T) must be representable as std::size_t.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if CUDA rejects the device allocation.
std::bad_allocIf host allocation or error-diagnostic construction fails.
std::length_errorIf count or an error diagnostic exceeds an implementation limit.
Postcondition
On success, both active lengths equal count and the device capacity equals count.
Warning
For nonzero count, the mirrors are not value-coherent until the caller initializes them with set() or performs an explicit transfer.

◆ CudaContainer() [3/8]

template<typename T >
CudaContainer< T >::CudaContainer ( const std::vector< T > &  other)

Constructs coherent mirrors by copying a host vector.

The input is borrowed only for the duration of construction. The host elements are deep-copied and an independent device allocation is created. For a nonempty source, the complete active range is copied from host to device and followed by cudaDeviceSynchronize().

Parameters
[in]otherHost vector whose other.size() contiguous elements are copied. Element units and component meaning are preserved unchanged. An empty source performs no CUDA transfer or synchronization.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device allocation, host-to-device copying, or device synchronization fails.
std::bad_allocIf host allocation or error-diagnostic construction fails.
std::length_errorIf the source length or an error diagnostic exceeds an implementation limit.
Postcondition
On success, both mirrors have other.size() elements and contain independent copies of other.

◆ CudaContainer() [4/8]

template<typename T >
CudaContainer< T >::CudaContainer ( const std::vector< T > &&  other)

Constructs coherent mirrors by copying a const host-vector rvalue.

This legacy overload performs the same deep copy, host-to-device transfer, and device-wide synchronization as the const-lvalue overload.

Parameters
[in]otherConst host-vector rvalue whose active elements are copied. The source is borrowed during construction and remains unchanged.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device allocation, host-to-device copying, or device synchronization fails.
std::bad_allocIf host allocation or error-diagnostic construction fails.
std::length_errorIf the source length or an error diagnostic exceeds an implementation limit.
Postcondition
On success, both mirrors contain independent copies of other.
Note
Because other is const, this overload does not move storage from the source.

◆ CudaContainer() [5/8]

template<typename T >
CudaContainer< T >::CudaContainer ( const DeviceVector< T > &  other)

Constructs coherent mirrors by copying a device vector.

The source is borrowed only for the duration of construction. Its active device elements are deep-copied into an independent device allocation and an equally sized host vector is created. For a nonempty source, the device range is copied to the host and followed by cudaDeviceSynchronize().

Parameters
[in]otherDevice vector whose active range [0, other.size()) is copied. The source allocation remains owned by other. An empty source performs no device-to-host transfer or synchronization.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device allocation, device-to-device copying, device-to-host copying, or synchronization fails.
std::bad_allocIf host allocation or error-diagnostic construction fails.
std::length_errorIf the source length or an error diagnostic exceeds an implementation limit.
Postcondition
On success, both mirrors have other.size() elements and contain independent copies of the source device values.

◆ CudaContainer() [6/8]

template<typename T >
CudaContainer< T >::CudaContainer ( const DeviceVector< T > &&  other)

Constructs coherent mirrors by copying a const device-vector rvalue.

This legacy overload performs the same device copy, device-to-host transfer, and device-wide synchronization as the const-lvalue overload.

Parameters
[in]otherConst device-vector rvalue whose active range is copied. The source allocation remains owned by other and is not modified.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device allocation, device-to-device copying, device-to-host copying, or synchronization fails.
std::bad_allocIf host allocation or error-diagnostic construction fails.
std::length_errorIf the source length or an error diagnostic exceeds an implementation limit.
Postcondition
On success, both mirrors contain independent copies of other.
Note
Because other is const, this overload does not move its allocation.

◆ CudaContainer() [7/8]

template<typename T >
CudaContainer< T >::CudaContainer ( const CudaContainer< T > &  other)

Constructs independent copies of another container's two mirrors.

The host mirror and device mirror are copied separately. No transfer is performed between them, so any value or length divergence already present in other is preserved in the new object.

Parameters
[in]otherContainer borrowed for the duration of construction.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device allocation or device-to-device copying fails.
std::bad_allocIf host allocation or error-diagnostic construction fails.
std::length_errorIf a mirror length or an error diagnostic exceeds an implementation limit.
Postcondition
On success, neither mirror aliases storage owned by other.
Note
The device copy uses cudaMemcpy without an explicit stream and does not issue an additional cudaDeviceSynchronize().

◆ CudaContainer() [8/8]

template<typename T >
CudaContainer< T >::CudaContainer ( const CudaContainer< T > &&  other)

Constructs independent copies of a const container rvalue.

The host and device mirrors are copied separately, exactly as for the const-lvalue copy constructor. Existing divergence between the source mirrors is preserved.

Parameters
[in]otherConst container rvalue borrowed during construction. Its storage and values remain unchanged.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device allocation or device-to-device copying fails.
std::bad_allocIf host allocation or error-diagnostic construction fails.
std::length_errorIf a mirror length or an error diagnostic exceeds an implementation limit.
Postcondition
On success, neither mirror aliases storage owned by other.
Note
Because other is const, this overload does not transfer ownership.

◆ ~CudaContainer()

template<typename T >
CudaContainer< T >::~CudaContainer ( void  )
defaultnoexcept

Destroys both owned mirrors without propagating cleanup failures.

Host storage is released normally. The device owner attempts cudaFree, discards its return status, and clears its metadata.

Postcondition
All references, host pointers, and device pointers borrowed from this object are invalid.

Member Function Documentation

◆ at() [1/2]

template<typename T >
T & CudaContainer< T >::at ( const std::size_t  pos)

Returns a checked mutable reference to one host element.

Mutating the returned reference changes only the host mirror. Call transferToDevice() before device code consumes the new value.

Parameters
[in]posZero-based, dimensionless host element index.
Returns
A borrowed mutable reference to host element pos. The reference is invalidated by owner destruction or any host-vector operation that invalidates references.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::InvalidArgument if pos >= size().
std::bad_allocIf construction of the invalid-index diagnostic fails.
std::length_errorIf the invalid-index diagnostic exceeds an implementation limit.
Postcondition
Mutation through the returned reference does not update the device mirror automatically.

◆ at() [2/2]

template<typename T >
const T & CudaContainer< T >::at ( const std::size_t  pos) const

Returns a checked const reference to one host element.

This method reads only the host mirror and performs no CUDA transfer.

Parameters
[in]posZero-based, dimensionless host element index.
Returns
A borrowed const reference to host element pos. The reference is invalidated by owner destruction or any host-vector operation that invalidates references.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::InvalidArgument if pos >= size().
std::bad_allocIf construction of the invalid-index diagnostic fails.
std::length_errorIf the invalid-index diagnostic exceeds an implementation limit.

◆ clear()

template<typename T >
void CudaContainer< T >::clear ( void  )

Clears both mirrors and releases the device allocation.

The host mirror is cleared first. The device owner then resets its active length and capacity and attempts to release its CUDA allocation.

Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if cudaFree reports failure.
std::bad_allocIf CUDA error-diagnostic construction fails.
std::length_errorIf the CUDA error diagnostic exceeds an implementation limit.
Postcondition
On success, both mirrors are empty and the device data pointer is null.
Warning
If device cleanup fails, the host mirror and device metadata are already empty and the old device allocation may remain reserved.

◆ getDeviceArray() [1/2]

template<typename T >
DeviceVector< T > & CudaContainer< T >::getDeviceArray ( void  )

Returns a borrowed mutable reference to the device mirror.

Direct device mutation bypasses host synchronization. Resizing, clearing, or replacing the nested device allocation can break the equal-length and ownership invariants expected by this container.

Returns
A borrowed mutable reference valid until this container is destroyed. No ownership is transferred.
Warning
Preserve getHostArray().size() == getDeviceArray().size() and the normal DeviceVector ownership invariant before calling transfers or printDeviceArray().

◆ getDeviceArray() [2/2]

template<typename T >
const DeviceVector< T > & CudaContainer< T >::getDeviceArray ( void  ) const

Returns a borrowed const reference to the device mirror.

The returned DeviceVector remains owned by this container. Its values can be stale relative to the host mirror until transferToDevice() runs.

Returns
A borrowed const reference valid until this container is destroyed. A device pointer obtained from it is invalidated according to DeviceVector reallocation and cleanup rules.

◆ getHostArray() [1/2]

template<typename T >
std::vector< T > & CudaContainer< T >::getHostArray ( void  )

Returns a borrowed mutable reference to the host mirror.

Direct element mutation bypasses device synchronization. Directly changing the vector's size can break the equal-length invariant required by transfer and print operations.

Returns
A borrowed mutable reference valid until this container is destroyed. No ownership is transferred.
Warning
Preserve getHostArray().size() == getDeviceArray().size() unless all later operations account explicitly for divergent lengths.

◆ getHostArray() [2/2]

template<typename T >
const std::vector< T > & CudaContainer< T >::getHostArray ( void  ) const

Returns a borrowed const reference to the host mirror.

The returned std::vector<T> remains owned by this container. Its values can be stale relative to the device mirror until transferToHost() runs.

Returns
A borrowed const reference valid until this container is destroyed. References or pointers to its elements follow normal std::vector invalidation rules.

◆ operator=() [1/6]

template<typename T >
CudaContainer< T > & CudaContainer< T >::operator= ( const CudaContainer< T > &&  other)

Replaces each mirror with copies from a const container rvalue.

This legacy overload copies the host and device mirrors separately and does not reconcile source divergence.

Parameters
[in]otherConst container rvalue borrowed during assignment. It remains unchanged.
Returns
A borrowed reference to this container.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device allocation, device-to-device copying, or device cleanup fails.
std::bad_allocIf host allocation or error-diagnostic construction fails.
std::length_errorIf a mirror length or an error diagnostic exceeds an implementation limit.
Postcondition
On success, both destination mirrors own independent copies of the corresponding source mirrors.
Warning
On failure after host assignment, the destination mirrors can diverge.
Note
Because other is const, this overload does not transfer ownership.

◆ operator=() [2/6]

template<typename T >
CudaContainer< T > & CudaContainer< T >::operator= ( const CudaContainer< T > &  other)

Replaces each mirror with the corresponding mirror from another container.

The host mirror is assigned first and the device mirror second. No transfer is performed between them; source divergence is copied as-is.

Parameters
[in]otherContainer borrowed for the duration of assignment.
Returns
A borrowed reference to this container.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device allocation, device-to-device copying, or device cleanup fails.
std::bad_allocIf host allocation or error-diagnostic construction fails.
std::length_errorIf a mirror length or an error diagnostic exceeds an implementation limit.
Postcondition
On success, both destination mirrors own storage independent of other and reproduce the corresponding source mirror.
Warning
On failure after host assignment, the destination mirrors can represent different source states.

◆ operator=() [3/6]

template<typename T >
CudaContainer< T > & CudaContainer< T >::operator= ( const DeviceVector< T > &&  other)

Replaces both mirrors with a copy of a const device-vector rvalue.

This legacy overload has the same transfer, synchronization, and failure behavior as assignment from a const device-vector lvalue.

Parameters
[in]otherConst device-vector rvalue borrowed during assignment. Its allocation and values remain unchanged.
Returns
A borrowed reference to this container.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device allocation, device-to-device copying, device-to-host copying, or synchronization fails.
std::bad_allocIf host allocation or error-diagnostic construction fails.
std::length_errorIf the source length or an error diagnostic exceeds an implementation limit.
Postcondition
On success, both mirrors contain independent copies of other.
Warning
On failure after device assignment, the two mirrors can diverge.
Note
Because other is const, this overload does not move from it.

◆ operator=() [4/6]

template<typename T >
CudaContainer< T > & CudaContainer< T >::operator= ( const DeviceVector< T > &  other)

Replaces both mirrors with a coherent copy of a device vector.

The device mirror is assigned first and the host mirror is resized. For a nonempty source, the complete device range is copied to the host and followed by cudaDeviceSynchronize().

Parameters
[in]otherDevice vector borrowed for the duration of the assignment. Its allocation remains owned by other. An empty source performs no device-to-host transfer or synchronization.
Returns
A borrowed reference to this container.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device allocation, device-to-device copying, device-to-host copying, or synchronization fails.
std::bad_allocIf host allocation or error-diagnostic construction fails.
std::length_errorIf the source length or an error diagnostic exceeds an implementation limit.
Postcondition
On success, both mirrors contain independent copies of the active source range.
Warning
On failure after device assignment, the device mirror can contain the new values while the host mirror has an old or partially updated state.

◆ operator=() [5/6]

template<typename T >
CudaContainer< T > & CudaContainer< T >::operator= ( const std::vector< T > &&  other)

Replaces both mirrors with a copy of a const host-vector rvalue.

This legacy overload has the same transfer, synchronization, and failure behavior as assignment from a const host-vector lvalue.

Parameters
[in]otherConst host-vector rvalue borrowed during the assignment. Its storage and values remain unchanged.
Returns
A borrowed reference to this container.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device resizing, host-to-device copying, or device synchronization fails.
std::bad_allocIf host allocation or error-diagnostic construction fails.
std::length_errorIf the source length or an error diagnostic exceeds an implementation limit.
Postcondition
On success, both mirrors contain independent copies of other.
Warning
On failure after host assignment, the two mirrors can diverge.
Note
Because other is const, this overload does not move from it.

◆ operator=() [6/6]

template<typename T >
CudaContainer< T > & CudaContainer< T >::operator= ( const std::vector< T > &  other)

Replaces both mirrors with a coherent copy of a host vector.

The host mirror is assigned first and the device mirror is resized. For a nonempty source, the complete host range is copied to the device and followed by cudaDeviceSynchronize().

Parameters
[in]otherHost vector borrowed for the duration of the assignment. No reference to it is retained. An empty source performs no CUDA transfer or synchronization.
Returns
A borrowed reference to this container.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device resizing, host-to-device copying, or device synchronization fails.
std::bad_allocIf host allocation or error-diagnostic construction fails.
std::length_errorIf the source length or an error diagnostic exceeds an implementation limit.
Postcondition
On success, both mirrors contain independent copies of other.
Warning
On failure after host assignment, the host mirror can contain the new values while the device mirror has an old or partially updated state.

◆ operator[]() [1/2]

template<typename T >
T & CudaContainer< T >::operator[] ( const std::size_t  pos)

Returns an unchecked mutable reference to one host element.

Mutating the returned reference changes only the host mirror.

Parameters
[in]posZero-based, dimensionless host element index.
Returns
A borrowed mutable reference to host element pos, subject to normal std::vector reference-invalidation rules.
Precondition
pos < size().
Postcondition
Mutation through the returned reference does not update the device mirror automatically.
Warning
Passing an out-of-range index has undefined behavior.

◆ operator[]() [2/2]

template<typename T >
const T & CudaContainer< T >::operator[] ( const std::size_t  pos) const

Returns an unchecked const reference to one host element.

This method reads only the host mirror and performs no CUDA transfer.

Parameters
[in]posZero-based, dimensionless host element index.
Returns
A borrowed const reference to host element pos, subject to normal std::vector reference-invalidation rules.
Precondition
pos < size().
Warning
Passing an out-of-range index has undefined behavior.

◆ printDeviceArray()

template<typename T >
void CudaContainer< T >::printDeviceArray ( void  ) const

Prints the active device mirror with CUDA device printf.

One default-stream kernel thread is assigned per element. Each emitted line contains the zero-based index followed by the scalar value or the CUDA vector components in x, y, z, w order. The method does not transfer host values to the device. It checks the immediate launch status and then calls cudaDeviceSynchronize() so device output is flushed before return.

Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if the immediate kernel-launch check or device synchronization fails.
std::bad_allocIf CUDA error-diagnostic construction fails.
std::length_errorIf the CUDA error diagnostic exceeds an implementation limit.
Precondition
size() > 0, size() is no greater than the maximum value of unsigned int, the active mirror lengths are equal, and the device mirror owns valid storage for the active range.
Postcondition
On success, the container values and allocations are unchanged.
Note
Output line order is not guaranteed across CUDA threads.
Warning
The printed values can be stale relative to the host mirror unless the caller first calls transferToDevice().

◆ push_back()

template<typename T >
void CudaContainer< T >::push_back ( const T &  value)

Appends one value to both mirrors.

The host append occurs first. The device owner may allocate a larger buffer, preserve the old device prefix, and then enqueue a one-thread write kernel on the default stream. The method checks only the immediate launch status and does not wait for the append kernel to finish.

Parameters
[in]valueElement value copied into the new host slot and passed by value to the device append kernel.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device allocation, prefix copying, cleanup, or the immediate kernel-launch check fails.
std::bad_allocIf host growth or error-diagnostic construction fails.
std::length_errorIf growth or an error diagnostic exceeds an implementation limit.
Postcondition
After a successful immediate launch check, both active lengths are increased by one and the device write is enqueued.
Warning
A failure after the host append can leave the mirrors with different lengths or values.
Existing host references and device pointers can be invalidated by growth. Prefer resize() followed by initialization when the final length is known.

◆ resize()

template<typename T >
void CudaContainer< T >::resize ( const std::size_t  count)

Resizes both active ranges without synchronizing their values.

The host vector is resized first and the device vector second. Growing the host value-initializes new elements. Newly exposed or allocated device slots contain unspecified bytes until written. Shrinking preserves the retained prefix independently in each mirror.

Parameters
[in]countNew dimensionless active element count for both mirrors. The byte count count * sizeof(T) must be representable as std::size_t.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device allocation, prefix copying, or cleanup fails.
std::bad_allocIf host growth or error-diagnostic construction fails.
std::length_errorIf count or an error diagnostic exceeds an implementation limit.
Postcondition
On success, both active lengths equal count.
Warning
Growing does not make the new host and device elements coherent. A failure after host resizing can leave the mirror lengths divergent.

◆ set() [1/3]

template<typename T >
void CudaContainer< T >::set ( const DeviceVector< T > &  values)

Replaces both mirrors with a coherent device-vector copy.

The active device range is deep-copied first and the host vector is resized. For a nonempty source, the full device range is copied to host memory and followed by cudaDeviceSynchronize().

Parameters
[in]valuesDevice vector borrowed for the duration of the operation. Its allocation remains owned by values. An empty source performs no device-to-host transfer or synchronization.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device allocation, device-to-device copying, device-to-host copying, or synchronization fails.
std::bad_allocIf host resizing or error-diagnostic construction fails.
std::length_errorIf the input length or an error diagnostic exceeds an implementation limit.
Postcondition
On success, both mirrors contain independent copies of the active device source range.
Warning
A failure after device assignment can leave the mirrors divergent.

◆ set() [2/3]

template<typename T >
void CudaContainer< T >::set ( const std::vector< T > &  values)

Replaces both mirrors with a coherent host-vector copy.

The host values are copied and the device active range is resized to match. For a nonempty source, the full host range is copied to device memory and followed by cudaDeviceSynchronize().

Parameters
[in]valuesHost vector borrowed for the duration of the operation. No reference to it is retained. An empty source performs no CUDA transfer or synchronization.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device resizing, host-to-device copying, or device synchronization fails.
std::bad_allocIf host assignment or error-diagnostic construction fails.
std::length_errorIf the input length or an error diagnostic exceeds an implementation limit.
Postcondition
On success, both mirrors contain independent copies of values.
Warning
A failure after host assignment can leave the mirrors divergent.

◆ set() [3/3]

template<typename T >
void CudaContainer< T >::set ( const T  value)

Sets every current element to one value in both mirrors.

The host mirror is filled without changing its active length. The complete host range is then copied to the device and followed by cudaDeviceSynchronize(). An empty host mirror makes the transfer a no-op.

Parameters
[in]valueElement value copied into every active slot. Its physical units, if any, are defined by the owning subsystem.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if host-to-device copying or device synchronization fails.
std::bad_allocIf CUDA error-diagnostic construction fails.
std::length_errorIf the CUDA error diagnostic exceeds an implementation limit.
Precondition
The active mirror lengths are equal and both nonempty mirrors own valid storage for that active range.
Postcondition
On success, both mirrors retain their current lengths and every active element equals value.
Warning
A transfer failure occurs after the host mirror has been filled and can leave the device mirror unchanged or partially updated.

◆ setToValue()

template<typename T >
void CudaContainer< T >::setToValue ( const T  value)

Sets every current element to one value in both mirrors.

This compatibility alias delegates directly to set(const T).

Parameters
[in]valueElement value copied into every active slot. Its physical units, if any, are defined by the owning subsystem.
Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if host-to-device copying or device synchronization fails.
std::bad_allocIf CUDA error-diagnostic construction fails.
std::length_errorIf the CUDA error diagnostic exceeds an implementation limit.
Precondition
The active mirror lengths are equal and both nonempty mirrors own valid storage for that active range.
Postcondition
On success, both mirrors retain their current lengths and every active element equals value.

◆ shrink_to_fit()

template<typename T >
void CudaContainer< T >::shrink_to_fit ( void  )

Requests capacity reduction for both mirrors without transferring values.

The host request is applied first. The device owner then reallocates to exactly its active size and preserves its active device prefix. Existing host/device value divergence is not reconciled.

Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if device allocation, device-to-device copying, or device cleanup fails.
std::bad_allocIf host shrinking or error-diagnostic construction fails.
std::length_errorIf an allocation request or error diagnostic exceeds an implementation limit.
Postcondition
On success, both active lengths are unchanged; device capacity equals device size. Host capacity reduction remains a non-binding request.
Warning
Host element references can be invalidated before a later device failure is reported. A device reallocation invalidates prior device pointers.

◆ size()

template<typename T >
std::size_t CudaContainer< T >::size ( void  ) const

Returns the active length of the host mirror.

Returns
Dimensionless number of elements in getHostArray().
Note
This method does not inspect the device mirror. The returned value can differ from getDeviceArray().size() after mutable mirror access or a partially completed operation.

◆ transferFromDevice()

template<typename T >
void CudaContainer< T >::transferFromDevice ( void  )

Transfers the complete device mirror to host memory.

This compatibility alias delegates directly to transferToHost() and has the same equal-length precondition, device-wide synchronization, and error behavior.

Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if copying or device synchronization fails.
std::bad_allocIf CUDA error-diagnostic construction fails.
std::length_errorIf the CUDA error diagnostic exceeds an implementation limit.
Precondition
The active mirror lengths are equal and both nonempty mirrors own valid storage for that active range.
Postcondition
On success, the active host values equal the active device values.

◆ transferFromHost()

template<typename T >
void CudaContainer< T >::transferFromHost ( void  )

Transfers the complete host mirror to device memory.

This compatibility alias delegates directly to transferToDevice() and has the same equal-length precondition, device-wide synchronization, and error behavior.

Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if copying or device synchronization fails.
std::bad_allocIf CUDA error-diagnostic construction fails.
std::length_errorIf the CUDA error diagnostic exceeds an implementation limit.
Precondition
The active mirror lengths are equal and both nonempty mirrors own valid storage for that active range.
Postcondition
On success, the active device values equal the active host values.

◆ transferToDevice()

template<typename T >
void CudaContainer< T >::transferToDevice ( void  )

Transfers the complete host mirror to device memory.

For a nonempty host mirror, the method copies size() contiguous elements with cudaMemcpyHostToDevice and then calls cudaDeviceSynchronize(). It does not allocate, resize, or select a stream. An empty host mirror returns without issuing a CUDA call.

Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if copying or device synchronization fails.
std::bad_allocIf CUDA error-diagnostic construction fails.
std::length_errorIf the CUDA error diagnostic exceeds an implementation limit.
Precondition
The active mirror lengths are equal and every nonempty mirror owns valid storage for at least size() elements.
Postcondition
On success, the active device values equal the active host values.
Warning
This call synchronizes all previously requested work on the current CUDA device, not only work associated with this container.

◆ transferToHost()

template<typename T >
void CudaContainer< T >::transferToHost ( void  )

Transfers the complete device mirror to host memory.

For a nonempty host mirror, the method copies getDeviceArray().size() contiguous elements with cudaMemcpyDeviceToHost and then calls cudaDeviceSynchronize(). It does not allocate, resize, or select a stream. An empty host mirror returns without issuing a CUDA call.

Exceptions
ApoCharmmErrorWith ApoCharmmErrorCode::Cuda if copying or device synchronization fails.
std::bad_allocIf CUDA error-diagnostic construction fails.
std::length_errorIf the CUDA error diagnostic exceeds an implementation limit.
Precondition
The active mirror lengths are equal and every nonempty mirror owns valid storage for that active range.
Postcondition
On success, the active host values equal the active device values.
Warning
This call synchronizes all previously requested work on the current CUDA device, not only work associated with this container.